程式大致上正确的,但没有考虑到容错,比如用户输入16进制之外的字符比如AS$H之类...
不喜欢这种写法.
这里我随便就题目写了另一种方式,而输出是用原代码的,你可以编译一下试试效果,随便乱搞一些字符看看它如何处理.
附有解释,看看能不能理解
程序代码:
DATA SEGMENT
HexTable db '0123456789ABCDEF';16进制字符表1,数字符和大写
HexTable1 db 'abcdef' ;16进制字符表2,小写
Len equ $ - offset HexTable ;16进制表1&2的总长
DATA ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV ES,AX ;ES取值,用以操作scasb
mov bl,4 ;输入4次初始化
mov si,0 ;用以保存输入,初始化
cld ;清除方向标志,正向
next:
mov ah,07h ;输入函数,不显示
int 21h ;dos调用,al=输入字符
mov cx,Len ;总长
lea di,HexTable ;指向16进制字符表
repnz scasb ;以al扫瞄es:di cx次,每扫一次,di+1,cx-1
;直至找到字符或扫完则停
jnz next ;输入字符不在表中,重新输入
cmp di,offset HexTable1 ;di地址和'小写表地址'比较
jbe @f ;di在表1则跳
sub di,6 ;减去表2和表1的差距
@@: sub di,offset HexTable+1;再减16进制字符表1,'+1'是调整找到字符时di加多了1
mov cl,4 ;初始化
shl si,cl ;将上次输入移左4位,若第1次输入F,其结果是0000 or 000F = 000F
or si,di ;若第2次输入B,其结果是00F0 or 000B = 00FB
;若第3次输入4,其结果是0FB0 or 0004 = 0FB4,余类推
mov dl,al ;DL=输入字符
mov ah,2
int 21h ;输出
dec bl ;减1
jnz next ;未完则再来
mov dl,0dh ;以下输出回车0D0AH
mov ah,2
int 21h
mov dl,0ah
int 21h
;
mov cx,16 ;初始化
@@: mov dl,0 ;初始化
rol si,1 ;左旋,最左BIT旋入CF,CF=1或0
adc dl,30h ;带进位(CF)加DL,则若CF=1,则DL='1',否则DL='0'
mov ah,02h
int 21h ;输出
loop @b ;回圈
MOV AH,4CH
INT 21H
CODES ENDS
END START
[此贴子已经被作者于2020-5-3 20:46编辑过]