NASM汇编打印Hello World乱码问题排查求助
问题排查与修复
核心问题1:字符串缺少空终止符
你的msg定义仅包含字符串和换行符,但未添加**空字节(0)**作为结束标记,导致循环中的or al, al永远无法触发终止条件,程序会持续读取后续内存中的随机数据并输出,进而产生乱码。
修复:在字符串末尾追加空字节:
msg db 'Hello, world!',0xa, 0 ; 新增0作为终止符
核心问题2:初始指针错误跳过首字符
代码中mov si, msg后直接执行inc si,导致第一个字符'H'被跳过,且后续循环从第二个字符开始读取。
修复:调整循环逻辑,先读取字符再递增指针:
_start: mov si, msg loop: mov ah, 0x0e mov al, [si] or al, al jz end ; 读取到空字符时终止循环 mov bh, 0x00 int 0x10 ; 输出当前字符 inc si ; 指针后移,准备读取下一个字符 jmp loop end: jmp .done
潜在问题3:磁盘读取未做错误检查
引导加载程序调用int 0x13(磁盘读)后,未检查进位标志(CF)判断读取是否成功。若磁盘读取失败,加载到0x1000:0的内容为无效数据,执行后必然出现乱码。
修复:添加错误检查逻辑:
boot: mov ah, 0x02 mov al, 0x01 mov ch, 0x00 mov cl, 0x02 mov dh, 0x00 mov dl, 0x00 mov bx, 0x1000 mov es, bx int 0x13 jc disk_error ; CF置位则说明读取失败 jmp 0x1000:0x00 disk_error: jmp $ ; 读取失败时进入死循环 times 510 - ($ - $$) db 0 dw 0xAA55
修复后的完整被加载程序代码
org 0 bits 16 section .text global _start _start: mov si, msg loop: mov ah, 0x0e mov al, [si] or al, al jz end mov bh, 0x00 int 0x10 inc si jmp loop end: jmp .done .done: jmp $ msg db 'Hello, world!',0xa, 0 ; 新增空终止符 len equ $ - msg TIMES 510 - ($ - $$) db 0 DW 0xAA55
内容的提问来源于stack exchange,提问作者MastersProgression
相关产品推荐
相关产品推荐

