问题描述
从键盘输入一系列字符串并以"$"结束,然后统计其中的非数字字符,并用二进制显示出计数结果。
进制转换简单阐述
将16进制数除以2,保存所得余数(0也要保存),若商不为0,则再将商作为新的被除数,直到商为0。下面以16进制数“4”的转换为例:
首先,先将4除以2,得到的商 = 2和余数 = 0,这个商(2)就作为下一次除法的被除数,余数就是转换后二进制的第0位。
然后,再将上次得到的商(2)作为新的被除数,除以2,即可得到商 = 1和余数 = 0. 这里的商(1)就是下次除法运算时的被除数。
最后,再将上次得到的商(1)作为新的被除数,除以2,即可得到商 = 0和余数 = 1. 由于商=0,所以运算结束。要得到的二进制数就是( ),即 =
实现代码
; 从键盘输入一系列字符串并以"$"结束,然后统计其中的非数字字符,并用二进制显示出计数结果
DATA SEGMENT
MAX_LENGTH DB 100 ; 字符串STRING最大长度
ActualLength DB 0 ; 字符串STRING实际长度
STRING DB 100 DUP(?) ; 字符串STRING
ChangeRow DB 0DH, 0AH, 24H ; 换行符(0DH表示换行、0AH表示回车、24H表示"$"字符串结束符)
MES DB 'The Binary Code Result is:$'
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA, CS:CODE
START:
; 初始化
MOV AX, DATA
MOV DS, AX
; 输入字符串
MOV DX, OFFSET MAX_LENGTH
MOV AH, 10
INT 21H
; 输出换行符
MOV DX, OFFSET ChangeRow
MOV AH, 9
INT 21H
; 输出提示信息
MOV DX, OFFSET MES
MOV AH, 9
INT 21H
MOV SI, OFFSET STRING ; SI用来表示当前STRING字符串的下标
XOR DX, DX ; DX用于统计非数字的个数
MOV CL, ActualLength ; CL循环次数为字符串STRING的实际长度
C1:
MOV BL, [SI] ; 将当前下标SI的字符移入BL中
CMP BL, 24H ; 判断是否为结束符 '$'
JE END_LOOP ; 如果是'$'则跳出循环
INC DX ; 如果不是'$',先默认这个字符不是数字(计数器DX自增)
CMP BL, 30H ; 比较当前字符与30H('0')的大小
JL C2 ; 如果小于30H,说明不是数字
CMP BL, 39H ; 如果大于30H,再判断与39H('9')的大小
JG C2 ; 如果大于39H,说明不是数字
DEC DX ; 如果是数字,则把之前自增的DX减去1
; C2用来移动字符串中的下标SI,进入下一次循环
C2:
INC SI
LOOP C1
; 循环结束
END_LOOP:
MOV AX, DX ; AX存储非数字的个数
XOR CX, CX ; 统计除法运算次数(输出多少位的二进制数)
MOV BX, 2 ; 存储除数2
CHANGE_TO_TWO:
XOR DX, DX ; 将被除数的高位清零
DIV BX ; (DX, AX) / BX,运算后的AX为商,DX为余数
PUSH DX ; 保存余数
INC CX
CMP AX, 0 ; 判断AX(商)与0之间的大小关系
JNZ CHANGE_TO_TWO ; 如果AX(商)不为0,则继续进行除法运算
PRINT:
POP DX ; 栈结构先进后出(先输出高位,最后输出低位)
ADD DX, 30H ; 转换为ASCII码
; 输出单个字符(DL)
MOV AH, 2
INT 21H
LOOP PRINT
; 程序结束
MOV AH, 4CH
INT 21H
CODE ENDS
END START
运行结果展示
运行的时候,输入字符串:abcD123$,即可获得结果100. 其中非数字字符有a、b、c和D四个字符。('$'作为结束符,不算在里面)