如何在EMU8086中打印输出计算得到的数值
问题原因
你输出乱码的核心原因是误用了DOS中断int 21h的09H子功能:该功能要求传入的DX必须是以$结尾的ASCII字符串的首偏移地址,你直接将计算得到的数值传入输出,数值对应的是ASCII控制字符、符号编码,自然会出现笑脸、¶这类乱码。
另外你原有代码里存在逻辑错误:
MOV [SI+18],OFFSET IE MOV [SI+18],BX
这两行先后往同一个地址写值,第一行的偏移地址会被第二行的BX值直接覆盖,属于无效代码。
解决方法
你需要先将计算得到的十六进制/二进制数值,逐位转换为可显示的ASCII数字字符,存入缓冲区后再调用中断输出,转换逻辑如下:
- 提前在数据段定义输出缓冲区,预留至少6字节空间(16位整数最大是5位十进制数+1位$结尾符)
- 把待输出的16位数值逐次除以10,每次取余数加
30H(即字符'0'的ASCII编码),得到对应位的数字字符 - 由于取余得到的是从低位到高位的数字,我们直接从缓冲区末尾开始存字符,就无需额外做反转操作,最后在末尾补$
- 调用
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
相关产品推荐
相关产品推荐

