不是07C0:0000,x86机器上的物理地址与0000:7C00相同吗?

我的问题的理由是, Starman似乎相信GRUB Legacy作者的解释 (请参阅以下莫名其妙的代码:

7C4B EA507C0000 JMP 0000:7C50 ; Long Jump to the next instruction ; because some bogus BIOSes jump to ; 07C0:0000 instead of 0000:7C00. 

当我执行Intel指定的algorithm来构build第一个内存引用的有效地址时,我将07C0乘以16(实际上左移四位或一个半字节)。 然后我加上偏移量:0000,得到小数地址31,744。

如果我左移了第二个内存引用四位的段,我仍然有0000:和偏移量:7C00仍然寻址位置31,744。 所以我的直觉反应是这个GRUB Legacy引导扇区代码的作者拉我们的腿。 不pipe任何BIOS的内存引用的forms,如果有效地址计算为十进制31,744,那么这个跳远似乎没有问题解决。

假设代码的作者只是以一种看起来与正确的物理位置相同的方式表示伪造的物理内存位置,我开始考虑如何处理一个发送错误地址的BIOS。 五字节跳远似乎不是解决任何问题的方法。 五个NOP将用于相同的目的(事实上,简单地开始引导扇区代码提前五个字节,并且消除跳远将具有与跳到下一个指令的跳转相同的效果)。

如果BIOS跳转到正确的位置(7C00),没问题。 如果BIOS跳转到7C00以上的位置,那么在7C00加载的代码就不能解决这个问题。 如果BIOS跳转到7C00和7C4B之间的某个位置,那么存储在该区域的数据(或者解释为字节丢失的指令)可能会导致崩溃。 如果BIOS跳转到7C4B,TEST指令将被覆盖(通过跳转),JNZ到7C54将根据BIOS中执行的最后一个math运算来执行。

对于7C4B以下的BIOS跳转,错误alignment的指令可能会导致崩溃。 祝你好运,引导扇区代码的一部分将被执行。 这种执行的结果将取决于BIOS跳到的“假”内存地址。 那么这个引导扇区代码的作者拉着我们的腿“故障BIOS跳到错误的位置”的故事?

我在Luke Luo的博客中注意到,GRUB2引导扇区虽然不同于GRUB Legacy引导扇区,但保留了这种莫名其妙的跳跃 。 因此,如果GRUB Legacy引导扇区的原作者正在为我们开玩笑,这是一个非常成功的笑话(它已经完全重写了GRUB)。 我还剩下一些select,相信对一些未命名的BIOS有一个令人难以置信的断言,并且解决这个问题似乎实际上什么都不做, 或者相信原始引导部门的作者在为我们开玩笑。

卢克罗似乎接受了写入7P66和7C67的NOP指令,作为他没有跳到错误位置的BIOS的证据。 由Linux Mint 13写入我的闪存驱动器的GRUB2引导扇区具有相同的NOP。 然而,写在笔记本电脑硬盘上的GRUB2引导扇区(Debian Etch)却跳到了下一条以7C66和7C67编写的指令(请注意,Luke Luo向我们展示了存储在/ usr / lib / grub / i386-pc / boot.img具有Debian值)。 两个替代scheme都具有相同的效果(执行后面的指令),所以两个引导扇区都可以工作。 在引导扇区中,只有大约450字节的代码可以加载另一个扇区并执行它(包括错误消息,当这种简单的操作发生什么错误时,以及错误消息的八字节地址部门本身)。

所以我错过了什么东西,或者我确定了一个应该从GRUB引导扇区中删除的kludge(为更有意义的代码腾出空间)?

你错过了CPU的实际状态的差异(而物理地址相同的,这是正确的)。

BIOS执行JMP 0000:7C00

你的第一条指令位于cs=0000, ip=7C00 ,并且你的机器代码必须被编译用于这种重定位,只要它进行任何绝对寻址,例如mov ax,cs:[myTable] (然后myTable就可以是像0x7F00 )。

BIOS执行JMP 07C0:0000

你的第一条指令位于cs=07C0, ip=0000 ,所以像myTable这样的东西更像是0x0300

因此,代码开始处的第一个跳转会将相同的物理地址31,744“归一化”为期望的cs:ip形式,使得引导加载程序代码中的绝对地址的其余部分正常工作。