MBR的start.S中AX寄存器的两种赋值方式是否影响后续代码?
两种MBR段寄存器初始化方式的差异影响
这两种写法是否会影响后续代码,取决于BIOS加载MBR时CS寄存器的初始值,具体分析如下:
背景:MBR的加载环境
BIOS会将MBR加载到物理地址0x7C00处,但不同BIOS实现会用两种不同的CS:IP组合指向这个物理地址:
- 组合1:
CS=0x0000,IP=0x7C00(物理地址计算:0x0000 << 4 + 0x7C00 = 0x7C00) - 组合2:
CS=0x07C0,IP=0x0000(物理地址计算:0x07C0 << 4 + 0x0000 = 0x7C00)
两种写法的差异分析
写法1:用CS初始化段寄存器
movw %cs, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss
这种写法会把ds/es/ss设为和CS相同的值:
- 如果是组合1(CS=0x0000),则ds/es/ss=0x0000,和写法2结果一致
- 如果是组合2(CS=0x07C0),则ds/es/ss=0x07C0,和写法2的结果产生差异
写法2:直接置0段寄存器
xorw %ax, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss
这种写法固定将ds/es/ss设为0x0000,无论CS初始值是什么。
对后续代码的影响
当BIOS采用组合2(CS=0x07C0)时,两种写法会导致内存寻址的基址不同:
- 写法1下,访问
[0x100]对应的物理地址是0x07C0 <<4 + 0x100 = 0x7D00 - 写法2下,访问
[0x100]对应的物理地址是0x0000 <<4 + 0x100 = 0x0100
这会导致后续代码中访问数据、跳转指令(如jmp、call)或栈操作(依赖ss)指向错误的物理内存区域,引发逻辑错误甚至系统崩溃。
如果BIOS采用组合1,两种写法完全等价,不会有任何影响。
最佳实践
为了兼容所有BIOS实现,推荐使用写法2(直接置0段寄存器),或者在初始化后通过jmp 0x0000:next这样的远跳转强制将CS设为0,统一所有段寄存器的基址,避免寻址歧义。
内容的提问来源于stack exchange,提问作者ruoqiu
相关产品推荐
相关产品推荐

