关于XLAT查表指令输出的头疼问题,实在不知道为什么会这样。
关于XLAT查表指令输出的头疼问题,实在不知道为什么会这样。书上习题:从键盘输入一串可显示的字符(以回车键结束),并按字母,数字,空格分类计数,然后显示这3类的统计结果。
原因: 我编译运行在CMD下运行的。我用 INT 21H 02H号功能输出十进制数字的统计结果(配合XLAT指令找出要输出的ASCII码给 DL ),
不知道为什么会输出的 数字是乱码显示。
然后我就用Debug进行了调试。 结果在Debug调试下输出却是正确的十进制数字统计结果出来。
但是我将SHOW子程序里面的这句 MOV AL,L_RET 改为 MOV AL,05H 任意立即数 编译运行就正确。
请教各位高手帮帮忙,菜鸟感激不尽
就是下面的这段代码为输出的。
SHOW:
LEA DX,SHOW_L ;我把蓝色部分删除了也不行
MOV AH,09H
INT 21H
MOV BX,OFFSET ASCII_TAB
MOV AL,L_RET ;L_RET字节变量 统计字母的个数
XLAT ;将AL中的数字转换为ASCII吗
MOV DL,AL ;要显示的字符 DL=要显示的ASCII码
MOV AH,02H ;2号功能
INT 21H ;调用中断
MOV AH,4CH
INT 21H
CODE ENDS
END MAIN
完整源程序:
DATA SEGMENT
DB 64H ;定义输入缓冲区, 第一个单元为字符缓冲区限制的长度 最大为255字节
DB ? ;实际输入缓冲区长度
DB 64H DUP(?) ;开始第一个字符的接收
L_RET DB 0
N_RET DB 0
S_RET DB 0
;SHOW子程序使用
SHOW_L DB "LETTER: $"
SHOW_N DB "NUMBER: $"
SHOW_S DB "SPACE: $"
;利用查表指令转化子程序返回值为ASCII码,因为DL要使用,用02号功能输出结果。
ASCII_TAB db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
DATA ENDS
;Code Segment
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
MAIN: MOV AX,DATA
MOV DS,AX
MOV SI,2 ;将从字符串缓冲区第一个字符开始
MOV AH,0AH ;接收输入功能号0AH
INT 21H
XOR CX,CX
MOV CL,[SI-1] ;取得输入字符的个数,用作循环条件
XOR BX,BX ;子程序返回值初始化
XOR DH,DH
CALL LETTER ;开始调用子程序统计各个数量
;子程序-统计字母个数
;返回值:BH=个数
LETTER: MOV AL,[SI]
CMP AL,41H
JB NOP1 ;JB AL<41H(A) 调转,进行SI字符指针+1
CMP AL,5AH
JA NOP1 ;JA AL>5A(Z)H 调转,进行SI字符指针+1
INC L_RET ;否则以上条件不成立,L_RET+1
NOP1: INC SI
LOOP LETTER
MOV SI,2 ;这个很重要,恢复字符串指针,供其他子程序的正确处理
MOV CL,[SI-1]
CALL NUMBER
;子程序-统计数字个数
;返回值:DH=个数
NUMBER: MOV AL,[SI]
CMP AL,30H
JB NOP2 ;JB AL<30H(0) 调转,进行SI字符指针+1
CMP AL,39H
JA NOP2 ;JA AL>39H(9)H 调转,进行SI字符指针+1
INC N_RET ;否则以上条件不成立 N_RET+1
NOP2: INC SI
LOOP NUMBER
MOV SI,2 ;这个很重要,恢复字符串指针,供其他子程序的正确处理
MOV CL,[SI-1]
CALL SPACE
;子程序-统计空格个数
;返回值:BL=个数
SPACE:MOV AL,[SI]
CMP AL,20H
JZ AD ;等于20H 调转AD 进行ADD BL,1 空格统计
JMP NOP3
AD: INC S_RET
NOP3: INC SI
LOOP SPACE
XOR AL,AL ;为输出做准备
;输出统计结果。
SHOW:
LEA DX,SHOW_L
MOV AH,09H
INT 21H
MOV BX,OFFSET ASCII_TAB
MOV AL,L_RET
XLAT
MOV DL,AL ;要显示的字符 DL=要显示的ASCII码
MOV AH,02H ;2号功能
INT 21H ;调用中断
MOV AH,4CH
INT 21H
CODE ENDS
END MAIN