MBR程序在物理机显示错误文本的问题排查与修复求助
问题原因分析
你的MBR程序在物理机上文本内容显示错误,核心原因是段寄存器寻址不匹配:
- BIOS将MBR加载到内存地址
0x7C00处,此时CPU的CS段寄存器值为0x07C0(因为0x07C0 * 16 + 0 = 0x7C00),程序的代码和字符串MESSAGE都位于CS段对应的内存区域。 - 你在初始化时将
DS设为0,导致后续通过[si]访问MESSAGE时,实际寻址的是0:si(即低地址内存,比如0xXX),而非CS:si(即0x7C00+XX的正确位置)。 - 物理机BIOS在启动过程中会使用或覆盖低地址内存区域(你测试发现的非AA字节被覆盖就是证据),因此读取到的不是你定义的"Hello world"字符串,而是被BIOS修改后的垃圾数据,最终导致文本显示错误。
修复方案
有两种简单有效的修复方式:
方式一:同步DS与CS段寄存器
在初始化段寄存器时,将DS设置为与CS相同的值,确保数据寻址指向MBR所在的内存区域:
section MBR vstart=0x7C00 mov sp, $$ ; 初始化段寄存器,让DS与CS同段 mov ax, cs mov ds, ax mov es, ax mov ss, ax mov fs, ax ; 之后再设置视频内存的ES段 mov ax, 0xB800 mov es, ax ; 后续代码保持不变...
方式二:使用CS段前缀访问字符串
如果不想修改DS的设置,可以在读取字符串时显式使用CS段前缀,强制从代码段读取数据:
cycle: mov al, [cs:si] ; 加上cs:前缀,确保从CS段读取MESSAGE mov [es: di], ax add si, 1 add di, 2 sub cx, 1 cmp cx, 0 ja cycle
额外优化建议
- 栈指针
mov sp, $$将栈顶设为0x7C00,栈会向下增长,可能覆盖MBR自身的代码或数据,建议将栈设置到更安全的区域,比如把mov sp, 0x7C00改为mov sp, 0x7BFF(栈从MBR上方开始向下增长),或者直接设置到0x0000:0xFFFF这样的高地址区域。
内容的提问来源于stack exchange,提问作者aszswaz
相关产品推荐
相关产品推荐

