DOSBox中NASM编写的Hello World程序输出乱码的原因及解决方法
DOSBox下NASM编写Hello World乱码问题分析与解决
问题场景
出于学习目的,在DOSBox环境用NASM写了如下Hello World程序:
section .data hello db 'Hello, World!', 0 section .text global _start _start: ; 打印信息到屏幕 mov ah, 9 ; AH=9 表示“打印字符串”功能 mov dx, hello ; 将hello的偏移地址加载到DX int 21h ; 调用DOS中断21h执行该功能 ; 退出程序 mov ah, 4Ch ; AH=4Ch 表示“退出”功能 xor al, al ; 将AL设为0(返回码) int 21h ; 调用DOS中断21h退出程序
编译命令:
nasm -f bin hello.asm -o hello.com
运行时输入hello.com,但程序未输出预期内容,反而显示大量乱码。
错误原因
出现乱码有两个核心原因:
- COM文件缺少
org 100h伪指令:DOS下的COM程序会被加载到内存偏移0x100的位置(前0x100字节是PSP程序段前缀),如果没有指定org 100h,NASM会默认从偏移0开始生成机器码,导致程序中引用的字符串地址计算错误,DOS中断读取到错误的内存区域内容。 - 字符串终止符错误:DOS中断
int 21h的AH=9功能要求打印的字符串必须以**美元符号$**作为终止标记,而代码中用了0(NULL)作为结束符,中断会一直读取内存直到遇到$,这就会把后续无关的内存内容(乱码)也打印出来。
解决方法
修改代码,补上org 100h并将字符串终止符换成$,修正后的代码如下:
org 100h section .data hello db 'Hello, World!', '$' section .text global _start _start: ; 打印信息到屏幕 mov ah, 9 ; AH=9 表示“打印字符串”功能 mov dx, hello ; 将hello的偏移地址加载到DX int 21h ; 调用DOS中断21h执行该功能 ; 退出程序 mov ah, 4Ch ; AH=4Ch 表示“退出”功能 xor al, al ; 将AL设为0(返回码) int 21h ; 调用DOS中断21h退出程序
验证步骤
重新用原编译命令编译:
nasm -f bin hello.asm -o hello.com
运行hello.com,即可正常输出Hello, World!。
内容的提问来源于stack exchange,提问作者Troir
相关产品推荐
相关产品推荐

