如果CPU超出20位总线的1mb限制,如何从地址0xfffffff0
(CS_base : 0xffff0000 + IP : 0xfff0
)中获取指令?
0xffff0000
我已经阅读了其他帖子;他们只是在谈论CS寄存器被硬连接以获得0xffff0000
基址的事实,而不是总线限制
答案 0 :(得分:2)
最初(例如,对于8088、8086、80186),物理地址为20位(提供1 MiB的物理地址空间)。上电和重置时,CS:IP设置为“ 0xF000:0xFFF0 = 0xFFFF0”,固件的ROM位于物理地址空间的末尾(例如,以物理地址0xFFFFF结尾)。
请注意,由于将“ segment:offset”转换为物理地址的方式(特别是“ physical = segment * 16 + offset”),该值不是“ 20位以上”。
还要注意,对于不适合20位的物理地址,最高位将被丢弃以使其适合20位(例如“ 0xFFFF:0xFFFE = 0xFFFF * 16 + 0xFFFE = 0x10FFEE = 0x0FFEE”)。这导致了特殊的黑客(“ A20门”)通过在释放80286时禁用第21条地址线(A20)来保持向后兼容性(并且物理地址大小增加到24位,从而提供16 MiB的物理地址空间)。>
80286发生的另一个变化是(为了支持保护模式)段寄存器(最初只是一个16位整数)获得了一些隐藏的部分-主要是向段寄存器添加了一个隐藏的“段基”值,因此(在保护模式下)您具有已加载到段寄存器中的可见值,并且段详细信息(基地址,限制)是从表(全局描述符表或本地描述符表)中加载的,而不是由以下项直接暗示的加载到段寄存器中的值后,将物理地址计算更改为使用隐藏值(例如“ physical = segment.base + offset”),并且在实模式下,基于段负载设置了段基(例如“ segment.base” = value * 16“),以便在实模式下都一样。
后来(从80386开始),物理地址空间的大小增加了(首先增加到32位,然后增加到36位,然后增加到“最大52位的体系结构”)。发生这种情况时,他们会在上电/复位时更改加载到CS隐藏部分中的值。具体来说,可见部分保持不变(0xF000),但隐藏的“段基础”部分设置为0xFFFF0000,因此它实际上变为“ 0xFFFF0000 + 0xFFF0 = 0xFFFFFFF0”。此外,固件的ROM已移至32位地址空间的末尾(例如,以物理地址0xFFFFFFFF结尾);并且(出于兼容性考虑)复制了一部分ROM(可能已解压缩)并放在旧地址的RAM中(结束于物理地址0x000FFFFF),并且配置了内存控制器,从而忽略了对“旧版ROM区域”的写入操作(因此它的行为仍然像ROM,但速度更快,因为RAM比ROM快。)
当然,现在(对于UEFI,理论上和/或一旦“混合BIOS + UEFI”在明年永久不存在),它就可以消失-无需将一部分ROM复制到“旧版ROM区域”无需将存储控制器配置为忽略对该区域的写操作;并且我们可以在0x00000000到0xBFFFFFFFF之间有一个大的(3 GiB?)正常可用RAM区域。
答案 1 :(得分:1)
8086有20位总线,复位后,CS寄存器设置为0xffff,IP设置为0x0000,从而使物理地址为0xffff0或20位。 20位可寻址空间CPU具有16位CS和IP寄存器,因此您所质疑的寄存器值(CS:0xffff0000 + EP:0xfff0)对于8086 CPU不正确。