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

Jam*_* P. 6 linux x86 assembly grub memory-address

我的问题的原因是,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.
Run Code Online (Sandbox Code Playgroud)

当我执行Intel指定的算法在第一个存储器参考上构造有效地址时,我将07C0:乘以16(实际上将其移位4位或半个字节).然后我添加偏移量:0000并得到小数地址31,744.

如果我左移第二个存储器的段参考四位我仍然有0000:并且偏移:7C00仍然寻址位置31,744.所以我的直觉反应是这个GRUB Legacy引导扇区代码的作者拉我们的腿.无论任何BIOS的内存引用形式如何,如果有效地址计算为十进制31,744,那么看起来这个Long Jump正在解决没有问题.

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

如果BIOS跳转到正确的位置(7C00),没问题.如果BIOS跳转到7C00以上的位置,则7C00上没有加载的代码可以解决该问题.如果BIOS跳转到7C00和7C4B之间的位置,那么存储在该区域中的数据(或者解释为缺少字节的数据)可能会导致崩溃.如果BIOS跳转到7C4B,则TEST指令将被覆盖(通过跳转),并且将根据BIOS中执行的最后一次数学运算执行JNZ至7C54.

对于低于7C4B的BIOS跳转,再次错误对齐的指令可能会导致崩溃.祝你好运,引导扇区代码的某些部分将被执行.这种执行的结果将取决于BIOS确实跳到的"虚假"内存地址.那么这个启动扇区代码的作者是如何用一个关于"虚假的BIOS跳到错误的位置"的故事拉我们的腿?

我在Luke Luo的BLOG中注意到,GRUB2引导扇区虽然与GRUB Legacy引导扇区不同,却保留了这种莫名其妙的跳远.因此,如果GRUB Legacy引导扇区的原作者对我们开玩笑,这是一个相当成功的笑话(它完全重写了GRUB后幸存下来).我选择相信一个关于一些未命名的BIOS的令人难以置信的断言以及解决这样一个问题的解决方案,这个问题似乎实际上什么也没做,或者相信原始引导扇区的作者对我们开玩笑.

Luke Luo似乎接受了向7C66和7C67写入NOP指令,作为他没有跳到错误位置的BIOS的证据.由Linux Mint 13写入我的闪存驱动器的GRUB2引导扇区具有相同的NOP.然而写入我的笔记本电脑硬盘驱动器的GRUB2引导扇区(由Debian Etch提供)与7C66和7C67的下一条指令短暂跳转(注意Luke Luo向我们展示了原始引导扇区存储在/ usr/lib/grub/i386-pc/boot.img具有Debian值).两种选择都具有相同的效果(执行它们之后的指令),因此两个引导扇区都有效.在引导扇区中我没有预期的效率,其中只有大约450个字节可用于必须加载另一个扇区并执行它的代码(包括错误消息,用于当该简单操作出现问题时以及该字节的8字节地址时部门本身).

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

Ped*_*d7g 6

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

当BIOS执行时JMP 0000:7C00:

您的第一条指令位于cs=0000, ip=7C00,并且只要它执行任何绝对寻址,就必须为这种重定位编译机器代码mov ax,cs:[myTable](例如,myTable可以是类似的0x7F00).

当BIOS执行时JMP 07C0:0000:

你的第一条指令就在cs=07C0, ip=0000,所以更像myTable0x0300.

因此,代码开头的第一个长跳将把相同的物理地址31,744"规范化"为预期的cs:ip形式,使得引导加载程序代码中的其余绝对地址正常工作.

  • @fjardon第一个链接的引导扇区反汇编中的`JMP [7C42]`指令必须工作.这是近乎间接的跳跃,所以它只改变IP而不是CS.DS:7C42的偏移量为8000,因此如果CS为07C0而不是0000,则代码将跳转到07C0:8000而不是预期的0000:8000设置引导扇区可能很简单,因此不会必要的,但看起来有很多可以改进的地方. (3认同)