You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:06:23