x86 CPU在物理地址0xFFFFFFF0处开始执行。 BIOS ROM位于地址空间的末尾。 CPU从ROM执行的第一条指令是远跳,导致重新加载CS段,因此从物理区0x000F0000 - 0x000FFFFF内执行下一条指令。
什么原因导致ROM在两个区域都做出响应? PC上有一些特殊的地址解码逻辑吗?我在Bochs源代码中发现了一条评论,该代码指出最后128K的BIOS ROM映射到0xE0000 - 0xFFFFF。但是我找不到更多关于此的信息。很明显,这是PC特有的,因为我有x86嵌入式主板,并且这种镜像不会发生在那里。我只能用近跳。
在PC上总是涉及一些地址解码逻辑,因为在物理地址空间中存在一些“孔/窗口”,通过它们可以访问BIOS ROM和I / O设备(例如视频卡)而不是RAM。这是出于设计原因,出于兼容性原因,旧程序仍然可以在较新的计算机上运行。
至于CPU在重置后开始执行的初始地址,如果查看文档,您会看到奔腾级CPU从这开始:
EIP = 0xFFF0
CS.Selector = 0xF000的
CS.Base = 0xFFFF0000地址
如果遵循正常的实模式寻址方案,则物理地址应为CS.Selector * 16 + IP,或者替换值为0xFFFF0。但是,CPU实际上使用CS.Base +(E)IP计算地址(在实际和16/32位保护模式下,但不在虚拟8086或64位保护模式下),因此CPU请求的第一个地址从内存中将是0xFFFFFFF0。您无法在该高地址处使用远跳转到ROM内的代码可能是因为加载到CS会将CS.Base重置为16 * CS.Selector的新值。因此,跳转到,例如,0xF000:0xFFF0将控制转移到0xFFFF0而不是0xFFFFFFF0,除非ROM也映射到存储器中的低位置,并且其中的代码适合与CS(.Selector)= 0xF000一起运行,它不会运行。
此外,如果PC被限制为最多16MB(就像在i80286和i80386SX上那样)或4GB(因为它在i80386DX /原始版本上),CPU和它周围的电路都不能支持所有32(或更多)地址线。 i80386和i80486)或240-52 字节(在64位能力的奔腾级CPU上)如果是这种情况,如果忽略物理地址空间中的多个高位,则可以说执行有效地从低于理论最大值的地址开始 - 16,例如0x00FFFFF0(i80286 / i80386SX)。
如果您需要解决电路板的问题,请参阅其文档和原理图,以了解ROM如何映射到其上的物理地址空间。