You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何打印整数而非ASCII值?汇编循环求和后输出整数的代码问题

嘿,我来帮你排查下这个问题!你的代码其实已经正确算出了数字总和(1+2+3+4+10=20),但核心问题出在打印环节——你用的DOS中断功能不对,导致输出的是ASCII字符而非数字本身,另外我也会教你如何正确打印整数。

你的代码里的核心问题
  • 打印功能误用mov ah, 02h + int 21h是DOS的「输出ASCII字符」功能,它会把DL寄存器里的数值当作ASCII码输出。你的总和是20,对应的ASCII是空格字符,所以屏幕上看不到预期的数字。
  • 补充:求和逻辑是没问题的——xor ax,ax清零累加器、mov bx,tabl指向数组首地址、循环累加字节元素的步骤都正确,最终AX里确实存着正确的总和20。
如何打印整数(十进制)

要打印整数,你需要先把二进制数值转换成十进制数字对应的ASCII字符,再逐个输出。比如20要拆成'2'和'0',它们的ASCII码分别是50和48。具体步骤是:

  1. 用除法拆分数字:把数值不断除以10,得到的余数就是当前的个位数字,将余数加48转换成ASCII(因为'0'的ASCII是48)。
  2. 用栈反转顺序:因为除法得到的数字是从个位到高位的顺序,压入栈再弹出就能变成我们阅读的高位到个位顺序。
  3. 逐个弹出栈内的ASCII字符,用02h功能打印。
修正后的完整代码
format MZ
stack sth:256
entry codeseg: main
segment sdat use16 ;ds segment x
tabl db 1,2,3,4,10
segment sth use16
db 256 dup (?)
segment codeseg use16
main:
mov ax, sdat
mov ds, ax
; 打开栈初始化代码,确保程序栈正常工作
mov ax, sth
mov ss, ax
mov sp, 256

xor ax,ax       ; AX清零,用来存储总和
mov bx,tabl     ; BX指向数组首地址
mov cx,5        ; 循环次数设置为5
add_loop:       ; 给循环起个清晰的名字,避免和add指令重名
add al,[bx]     ; 数组是字节类型,直接累加至AL更高效(AH初始为0)
inc bx
loop add_loop   ; CX减1,不为0则跳回循环

; 现在AX中是总和20,开始转换并打印
mov bx, 10      ; 设置除数为10,用于拆分数字
mov cx, 0       ; CX用来记录数字的位数
convert:
xor dx, dx      ; DIV指令使用DX:AX作为被除数,先清零DX
div bx          ; AX = AX / 10(商),DX = AX % 10(余数,即当前位数字)
add dl, 48      ; 把余数转换成对应的ASCII字符(0-9对应48-57)
push dx         ; 将ASCII字符压入栈,用于后续反转顺序
inc cx          ; 位数计数+1
cmp ax, 0       ; 检查商是否为0,不为0则继续拆分
jne convert

; 从栈中弹出字符并逐个打印
print:
pop dx          ; 弹出一位的ASCII码到DL
mov ah, 02h     ; DOS功能:输出DL中的ASCII字符
int 21h
loop print      ; CX减1,不为0则继续打印

; 程序正常退出
mov ax, 4c00h
int 21h
ret
关键部分说明
  • 求和优化:因为数组元素是字节,直接用add al,[bx]更高效,不需要操作整个AX寄存器。
  • 数字转ASCII:通过div 10拆分出每一位数字,加48是ASCII码的偏移量,确保数字0-9对应'0'-'9'。
  • 栈的作用:拆分得到的数字是个位→十位的顺序,压栈后弹出就变成十位→个位,符合我们的阅读习惯。
  • 栈初始化:把你注释掉的栈初始化代码打开,避免程序运行时出现栈溢出等潜在问题。

运行这段代码后,屏幕上就会正确打印出20了!

内容的提问来源于stack exchange,提问作者Paweł

火山引擎 最新活动