MBR程序输出ASCII字符串为何呈现5字符组分段现象?
MBR打印"Hello world"出现5字符分段的原因
在MBR程序中尝试打印"Hello world",代码如下:
section MBR vstart=0x7C00 mov sp, $$ ... ; Set the memory address of the graphics card to the ES register. mov ax, 0xB800 mov es, ax ... ; Output string to 0xB8000 mov byte [es: 0x00], 'H' mov byte [es: 0x02], 'e' mov byte [es: 0x04], 'l' mov byte [es: 0x06], 'l' mov byte [es: 0x08], 'o' mov byte [es: 0x10], ' ' mov byte [es: 0x12], 'w' mov byte [es: 0x14], 'o' mov byte [es: 0x16], 'r' mov byte [es: 0x18], 'l' mov byte [es: 0x20], 'd' mov byte [es: 0x01], STYLE mov byte [es: 0x03], STYLE ... mov byte [es: 0x19], STYLE mov byte [es: 0x21], STYLE jmp $ ; Set the style of the string, the background color is green, the text is blinking, and the foreground color is black. STYLE equ 0xA4 times 510-($-$$) db 0 db 0x55, 0xAA
运行后字符串以5个字符为一组分段,原因如下:
核心原因:字符偏移计算错误
在VGA文本模式下,显示缓冲区起始地址为0xB8000,每个屏幕字符对应连续2个字节:
- 偶地址字节:存储字符的ASCII码
- 奇地址字节:存储字符的显示属性(颜色、闪烁等)
你的代码中存在关键偏移错误:
打印完"Hello"的最后一个字符o(存在es:0x08,对应第5个字符的ASCII位)后,下一个空格字符错误写入es:0x10,而正确位置应为es:0x0A。这直接跳过了es:0x0A到es:0x0F这8个字节,对应屏幕上4个空白字符位置;后续"world"的所有字符偏移也整体后移,进一步扩大了空白间隔。
视觉上,"Hello"(5个字符)之后跟着4个空白+空格,形成了明显的分段效果,看起来像是以5个字符为一组分隔。
修复方案
将字符的ASCII码偏移按每次+2的步长连续排列,修正后的字符写入部分应为:
; Output string to 0xB8000 mov byte [es: 0x00], 'H' mov byte [es: 0x02], 'e' mov byte [es: 0x04], 'l' mov byte [es: 0x06], 'l' mov byte [es: 0x08], 'o' mov byte [es: 0x0A], ' ' mov byte [es: 0x0C], 'w' mov byte [es: 0x0E], 'o' mov byte [es: 0x10], 'r' mov byte [es: 0x12], 'l' mov byte [es: 0x14], 'd'
同时对应调整属性字节的偏移,确保每个字符的ASCII码和属性一一对应。
内容的提问来源于stack exchange,提问作者aszswaz
相关产品推荐
相关产品推荐

