如何在EMU 8086中用汇编语言实现255到0的数字倒计时输出?
解决汇编DOS程序输出数字倒计时(255到0)的问题
原代码用int 21h的AH=2h功能直接输出AX中的数值,导致显示乱码——因为这个功能是输出DL寄存器里的ASCII字符,而非十进制数字。比如AX=255时,DL=0FFh,对应ASCII表中的不可打印控制字符,自然会显示乱码。要输出十进制数字,必须先把二进制数值拆分成十进制的每一位,再将每一位转换为对应的ASCII码(数字0-9的ASCII码是'0'到'9',即十六进制30h到39h,给数字加'0'即可完成转换)。
针对0-255的范围,我们需要拆分出百位、十位、个位依次输出,以下是修正后的完整代码:
; multi-segment executable file template. data segment pkey db "press any key...$" ends stack segment dw 128 dup(0) ends code segment start: mov ax, data mov ds, ax mov es, ax mov ax, 255 ; 初始化倒计时起始值 loop_start: push ax ; 保存当前AX值,避免后续除法操作破坏 ; === 拆分百位并输出 === mov al, ah ; AX是0-255,AH为0,AL存当前数值 mov ah, 0 mov bl, 100 div bl ; AL=百位数字,AH=原数%100的余数 mov dl, al add dl, '0' ; 转ASCII码 mov ah, 2 int 21h ; 输出百位 ; === 拆分十位并输出 === mov al, ah mov ah, 0 mov bl, 10 div bl ; AL=十位数字,AH=个位数字 mov dl, al add dl, '0' mov ah, 2 int 21h ; 输出十位 ; === 输出个位 === mov dl, ah add dl, '0' mov ah, 2 int 21h ; 输出个位 ; 输出空格分隔数字,提升可读性 mov dl, ' ' mov ah, 2 int 21h pop ax ; 恢复AX原值 dec ax ; 倒计时递减 cmp ax, 0 jnz loop_start ; 未到0则继续循环 ; 原代码后续逻辑 lea dx, pkey mov ah, 9 int 21h mov ah, 1 int 21h mov ax, 4c00h int 21h ends end start
关键说明
- ASCII转换:十进制数字加
'0'(等价于十六进制30h)即可得到对应ASCII码,这是DOS下输出数字的核心转换逻辑。 - 多位数拆分:通过除法拆分每一位:
- 除以100得到百位,余数用于计算十位
- 余数除以10得到十位,最终余数就是个位
- 栈保护:用
push/pop保存AX的值,因为除法指令会修改AX寄存器,避免影响后续的倒计时递减操作。 - 分隔符:输出空格是为了区分每个数字,若需要每行输出一个数字,可把空格换成换行符
0Ah(同时建议搭配回车符0Dh,让光标回到行首)。
内容的提问来源于stack exchange,提问作者abdo-570
相关产品推荐
相关产品推荐

