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

如何在EMU8086中打印输出计算得到的数值

问题原因

你输出乱码的核心原因是误用了DOS中断int 21h的09H子功能:该功能要求传入的DX必须是以$结尾的ASCII字符串的首偏移地址,你直接将计算得到的数值传入输出,数值对应的是ASCII控制字符、符号编码,自然会出现笑脸、¶这类乱码。
另外你原有代码里存在逻辑错误:

MOV [SI+18],OFFSET IE
MOV [SI+18],BX

这两行先后往同一个地址写值,第一行的偏移地址会被第二行的BX值直接覆盖,属于无效代码。

解决方法

你需要先将计算得到的十六进制/二进制数值,逐位转换为可显示的ASCII数字字符,存入缓冲区后再调用中断输出,转换逻辑如下:

  1. 提前在数据段定义输出缓冲区,预留至少6字节空间(16位整数最大是5位十进制数+1位$结尾符)
  2. 把待输出的16位数值逐次除以10,每次取余数加30H(即字符'0'的ASCII编码),得到对应位的数字字符
  3. 由于取余得到的是从低位到高位的数字,我们直接从缓冲区末尾开始存字符,就无需额外做反转操作,最后在末尾补$
  4. 调用int 21h的09H子功能输出缓冲区即可
完整可运行代码示例

首先是数据段定义:

data segment
    Ie_msg db 'Current value: $'
    IE db 6 dup(?) ; 输出数字的缓冲区,预留6字节
data ends

然后新增数值转ASCII的工具函数:

; 入参:AX = 待转换的16位无符号整数
; 出参:DI = 转换完成的以$结尾的字符串首地址
num2ascii:
    mov di, offset IE + 5 ; 从缓冲区末尾开始存
    mov byte ptr [di], '$' ; 先放结尾的$
    mov cx, 10
num2ascii_loop:
    dec di
    xor dx, dx
    div cx
    add dl, 30h ; 余数转ASCII
    mov [di], dl
    test ax, ax ; 判断商是否为0,为0则转换结束
    jnz num2ascii_loop
    ret

修改你的islem函数:

islem: 
    MOV AX,[SI+14]
    MOV BX,[SI+10]
    MOV CX,[SI+2]
  
    SUB AX,BX
    SUB AX,CX
  
    MOV [SI+16],AX
  
    MOV DX,00H
    MOV AX,[SI+16]
    DIV BX ; 如果你要输出的是DX里的余数,自行把入参改成MOV AX,DX即可
  
    CALL NEWLINE
  
    mov dx, offset Ie_msg
    mov ah,9
    int 21h
  
    ; 新增:转换数值为ASCII再输出
    call num2ascii
    mov dx, di
    mov ah, 09h
    int 21h
ret

如果你的计算结果是有符号数,只需要在转换前先判断符号位,若为负就在字符串开头加'-'字符,再对绝对值做转换即可。

内容的提问来源于stack exchange,提问作者Bengisu Adsız

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 15:36:04