emu8086汇编程序运行输出异常 打印值为0问题咨询
问题根源
你的程序仅输出字符0的核心原因是段寄存器DS指向了错误的内存段,导致没有读取到你定义的VAR1的真实值5:
- 你使用
format MZ生成EXE程序时,用stack 256伪指令让emu8086自动生成栈段,这个隐式创建的栈段会被排布在你自定义的data_seg之前,但emu8086对这种写法的段地址重定位计算有偏差,你通过mov ax, data_seg拿到的段地址实际是隐式栈段的地址,不是数据段的地址。 - DS被设置为栈段地址后,
MOV DL,VAR1读取的是栈段对应偏移位置的内存值,这个位置默认初始值是0,后续ADD DL,30H把0转换成ASCII码0(对应30H),调用2号中断输出自然只打印0。
修复方案
根据你的使用场景二选一即可:
方案1:改用COM格式(适合emu8086下的小程序练习,写法最简单)
COM格式下所有段寄存器默认指向同一个内存段,不需要手动处理段地址重定位,修改后的代码如下:
org 100h ; COM格式要求入口固定在偏移100h位置 segment data_seg VAR1 DB 5 segment code_seg start: ;print the value MOV AH,02H MOV DL,VAR1 ADD DL,30H INT 21H ; wait for any key.... mov ah, 1 int 21h mov ax, 4c00h ; exit to operating system. int 21h
方案2:保留MZ EXE格式,手动定义栈段
放弃会生成隐式段的stack 256写法,手动明确定义栈段,避免emu8086的段地址计算偏差,代码如下:
format MZ entry code_seg:start ; set entry point ; 手动明确定义栈段,不用隐式栈生成 segment stack_seg stack db 256 dup(0) ; 预留256字节栈空间 stack_top: segment data_seg VAR1 DB 5 segment code_seg start: ; set segment registers: mov ax, data_seg mov ds, ax ; 手动设置栈段寄存器 mov ax, stack_seg mov ss, ax mov sp, stack_top ;print the value MOV AH,02H MOV DL,VAR1 ADD DL,30H INT 21H ; wait for any key.... mov ah, 1 int 21h mov ax, 4c00h ; exit to operating system. int 21h
验证方法
你可以在原代码执行完mov ds, ax后,通过emu8086的内存查看工具查看DS:0000位置的字节值,会发现该值是0而不是你定义的5;顺着内存往后找16个字节(对应段地址+10H),就能看到值为5的字节,也就是你实际定义VAR1的位置,就能印证上述问题。
内容的提问来源于stack exchange,提问作者Simone Sarugia
相关产品推荐
相关产品推荐

