TASM打印数字数组问题:数值存入指定数组位后打印乱码如何解决
问题根源
你当前代码的问题有两个:
- 你直接将计算得到的数值(比如15、9、4)写入了
nstr的字节单元,而DOS中断int 21h的09h打印功能只能识别ASCII编码,数值15对应的ASCII是控制字符,自然会打印出乱码符号。 - 你混淆了「数值存储」和「打印用ASCII存储」的区别:单个
db类型的数组单元最多可以存0~255的数值(当然可以存两位数的15),但要打印这个两位数,必须拆成十位和个位两个独立的ASCII字符才能正常显示。
解决方案1:数值存指定位置,打印时逐个转ASCII输出
这个方案完全符合题目要求的var1存nstr[3]、var1+var2存nstr[4]、总和存nstr[5]的存储规则,打印时逐个取出三个位置的数值,分别转成十进制字符输出:
.model small .STACK 100h .data var1 db 4 var2 db 5 var3 db 6 nstr db 7 dup(' ') .code .startup mov ax, dgroup mov ds, ax ; 按题目要求存数值到对应位置 mov al, var1 mov nstr[3], al ; var1存nstr[3] add al, var2 mov nstr[4], al ; var1+var2存nstr[4] add al, var3 mov nstr[5], al ; 总和存nstr[5] ; 准备打印:从nstr[3]开始逐个取3个数值 mov cx, 3 mov si, 3 print_loop: mov al, nstr[si] xor ah, ah mov bl, 10 div bl ; al存十位, ah存个位 ; 先打十位 mov dl, al add dl, 30h ; 转ASCII mov ah, 02h int 21h ; 再打个位 mov dl, ah add dl, 30h mov ah, 02h int 21h ; 可选:打印空格分隔三个数,不需要可以删掉 mov dl, ' ' int 21h inc si loop print_loop stop: mov ah, 4ch int 21h end
该代码运行后会输出04 09 15 ,如果不需要前导零,只需要在打印十位前加判断:如果十位数值为0就跳过该字符的打印即可。
解决方案2:转成ASCII存数组,一次性打印
如果你还是想用09h功能一次性打印整个数组,可以把每个数值拆成两个ASCII字符,存入对应的数组位置,7字节的nstr刚好可以存3个两位数(6字节)加1个结束符$:
.model small .STACK 100h .data var1 db 4 var2 db 5 var3 db 6 nstr db 7 dup(' ') .code .startup mov ax, dgroup mov ds, ax mov di, 5 ; 从数组末尾往前存 mov bl, 10 ; 处理总和 var1+var2+var3 mov al, var1 add al, var2 add al, var3 xor ah, ah div bl add ah, 30h mov nstr[di], ah ; 个位存nstr[5] dec di add al, 30h mov nstr[di], al ; 十位存nstr[4] dec di ; 处理var1+var2 mov al, var1 add al, var2 xor ah, ah div bl add ah, 30h mov nstr[di], ah ; 个位存nstr[3] dec di add al, 30h mov nstr[di], al ; 十位存nstr[2] dec di ; 处理var1 mov al, var1 xor ah, ah div bl add ah, 30h mov nstr[di], ah ; 个位存nstr[1] dec di add al, 30h mov nstr[di], al ; 十位存nstr[0] ; 加结束符 mov nstr[6], '$' ; 一次性打印 mov ah, 09h mov dx, offset nstr int 21h stop: mov ah, 4ch int 21h end
该代码运行后会直接输出040915,符合一次性打印数组的需求。
内容的提问来源于stack exchange,提问作者cicirio
相关产品推荐
相关产品推荐

