是的,加电后,所有 x86 CPU 都处于实模式,但在找到 CS 分配之前会出现奇怪的行为!
阅读完一些 x86 文档后,以下是事实:
上电后,‘CS寄存器’、‘CS缓存寄存器’和‘EIP’初始值为:
CS= F000h(应始终为 16 位宽!)
CS_segment_start_address= FFFF_0000h(32 位值,指向 RAM 中的某个位置?)。CS_segment_lenght= 0_FFFFh(20 位大小值,是的,这是 64KB)。
CS_segment“存在”在内存中。
CS_segment 是一个“读/写”块。
CS_segment 已被“访问”。
EIP = 0000_FFF0h
现在,请注意以下生活事实。
==SOF==(事实开始)
当获取新指令(处于任何模式:真实、受保护等)时,硬件寻址逻辑似乎总是使用一些“CS 缓存寄存器”值来确定要放置在地址总线引脚上的地址。具体来说:
Next_Instruction_Address_on_Bus= CS_segment_start_address + EIP
==EOF==(事实结束)
因此,上电后我们得到这些数字:
总线上的下一个指令地址= FFFF_0000h + 0000_FFF0h= FFFF_FFF0h
这意味着,我们是否可以在加电后访问 RAM 的最后一个角落,远离 1MB 的限制?是的!!!。圣格利亚!
但是等等,先别跑、跳!这只是为了(由软件开发人员)放置一个“远跳转”到某个代码块,该代码块有望位于 BIOS ROM 区域中!
然而,主板确保复位向量 (0xFFFFFFF0h) 处的指令远跳转到映射到系统 BIOS 入口点 (0x0000: 0x000F0000h) 的内存位置。总之,每个“主板”都实现了这种“跳跃黑客”。[古斯塔沃·杜阿尔特有一个很好的解释。查看他的智能博客:http://duartes.org/gustavo/blog/post/how-computers-boot-up/]
按照上面的解释,提到的最后一个“远跳转”是将使用表现良好的“实模式”值更新“CS_segment_start_address”:
像 CS= XYZW h这样的赋值(通过远“跳跃”、远“调用”或任何其他方式完成)被翻译为:
CS_segment_star_address= 000 X_YZW 0h(其中 XYZW是 CS 半字节值)
再次像往常一样使用 4 位左移、1MB 限制、64KB 段长度 cr..p!
最后几句话,我想这种行为是为了确保您的开机(启动?)代码始终位于 RAM 的最后一个角落。这样,它将留下大量 RAM 供未来操作系统处理。[老实说,对我来说,将这个“重置”向量放在“中断向量表”@向量 #0 中会更有意义]。
如果我错了,请纠正我。希望这可以帮助。
PD:什么是CS缓存寄存器?嗯,它是与正在使用的 CS 选择器关联的描述符值。所有其他段也具有此“高速缓存寄存器”值,以便快速访问。请记住,在 x86 CPU 上,您无法随意禁用“分段”。你必须处理它。阅读一些涉及分段的“保护模式”以了解更多信息...不幸的是(或幸运的是?)分段已经消失并过时了。寻呼已成功成为一种保护机制。
顺便说一句,维基百科的一些文章似乎是用错误的逻辑编辑的。小心一点!
| 归档时间: |
|
| 查看次数: |
1794 次 |
| 最近记录: |