题目:从键盘接收若干个 N 位的十进制数值(0~65535),并以二进制、十进制、十六进制三种数制形式显示其和。
要求:
(1)用子程序实现一个 N 位十进制数值的输入,在主程序的循环结构
中调用该子程序;
(2)当用户未输入数值,直接回车时,结束输入;
(3)输出的数据为多位十进制数据,而机器内部计算的和是十六进制
形式,需要进行数制转换,然后以十进制字符串的形式输出结果;
(4)程序中要求有必要的提示信息。
例如:用户在提示信息下输入三个数值:
Please input a number:15
Please input a number:30
Please input a number:45
程序显示运算结果
The sum is:0101 1010B
90D
5AH
代码如下:
DATA SEGMENT
STR1 DB 0AH,0DH,"Please input a number: $"
STR2 DB 0AH,0DH,"The sum is: $"
CRLF DB 0AH,0DH,'$'
; TABLE_H DB 41H,42H,43H,44H,45H,46H ;将十六进制的字符以表格形式存储
NUM DW ? ;用来保存新输入的数据
SUM1 DW ? ;存放十进制的计算结果
SUM2 DW ? ;存放十六进制的计算结果
SUM3 DW ? ;存放二进制的计算结果
SUM DW ? ;用来单独存放最后运算结果
DATA ENDS
STACK SEGMENT
DW 6 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV BX,10 ;以后每输入一次需要乘以10
MOV SUM1,0;初始化,将需要存储数据的地方全部清零
MOV SUM2,0
MOV SUM3,0
MOV SUM,0
CALL I1
I1 PROC ;从键盘输入十进制数字,并完成计算机内部计算
T1:
MOV CX,0
LEA DX,STR1
MOV AH,09H
INT 21H ;输入提示
C1:
XOR AX,AX ;将AX清零
MOV AH,01H
INT 21H
INC CX ;用来判断是否已经输入过数字,每输入一次数字,CX加1
CMP AL,0DH
JZ C3
C2:
CMP AL,0DH
JCXZ OUTPUT ;此处代表未输入数字,直接回车,则结束输入
CMP AL,0DH
JZ T1 ;此处代表之前已经输入过数字,检测到回车,所以开始新一轮的输入
CMP AL,30H
JB EXIT
CMP AL,39H
JA EXIT
SUB AL,30H ;将ASCII值转换为对应十进制数值
MOV AH,0 ;将AH清零
MOV NUM,AX
MOV AX,SUM2
MUL BX
JC EXIT
ADD AX,NUM ;将输入的数字与原来的数相加
JC EXIT ;溢出,直接退出
MOV SUM2,AX ;保存新和
JMP C1 ;持续输入数字
C3:
MOV DX,0 ;先DX清零
MOV DX,SUM2
MOV SUM2,0 ;为了新一轮的重新输入,将SUM2清零
;MOV SUM3,DX ;将SUM2中的值存到SUM3中
;MOV DX,0
;ADD DX,SUM3
ADD SUM,DX ;SUM1中保存最终运算结果
JC EXIT
DEC CX
JMP C2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OUTPUT:
LEA DX,STR2 ;输出提示
MOV AH,09H
INT 21H
CALL S3 ;输出二进制结果
LEA DX,CRLF
MOV AH,09H
INT 21H
CALL S1 ;输出十进制结果
LEA DX,CRLF
MOV AH,09H
INT 21H
CALL S2 ;输出十六进制结果
JMP EXIT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I1 ENDP
S1 PROC ;进行十进制的输出
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,SUM
MOV SUM1,AX ;将十六进制的数值送入SUM1中,方便后续运算
MOV BX,10 ;每次除以10,取余,将十六进制数转换成十进制数
D1:
XOR DX,DX ;将DX清零
XOR AX,AX ;将AX清零 ;;这一步可以不要,没啥用
MOV AX,SUM1 ;把数据送到AX中,进行除法指令
DIV BX ;若进行无符号数的双子或字相除时,所得的商和余数也是无符号数,分别放在AX和DX中
MOV SUM1,AX ;将商放在SUM1中
CMP DX,0
JZ D2 ;判断余数是否为0,若为0,则结束
ADD DL,30H ;将十进制转换成对应的ASCII码
MOV DH,0 ;将DH清零
PUSH DX
INC CX
CMP DX,0
JNZ D1 ;判断余数是否为0,若不为0,则继续进行取余运算
D2:
POP DX
DEC CX
MOV AH,02H ;单字符输出
INT 21H
CMP CX,0
JZ REV1
JMP D2
REV1:
MOV DL,44H ;将字符D作为最后的后缀输出
INT 21H
POP DX
POP CX
POP BX
POP AX
RET
S1 ENDP
S2 PROC ;进行十六进制的输出
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV DX,SUM ;将十六进制的数值送入DX中
MOV BX,DX ;把数据复制一份到BX中
MOV CL,4 ;将移位次数送入CL中
H1:
SHR DH,CL ;右移4位,取高四位
OR DH,30H ;做或运算
CMP DH,30H
JZ H2
CMP DH,39H
JBE X1 ;小于则直接输出
ADD DH,7 ;说明大于39H,加上7才到对应的ASCII码值
X1:
MOV DL,DH ;将数据送到DL中,等待输出
MOV AH,02H
INT 21H
H2:
MOV DH,BH ;还原DH中数值
AND DH,0FH ;保留DH中低四位的值
OR DH,30H
CMP DH,30H
JZ H3
CMP DH,39H
JBE X2
ADD DH,7
X2:
MOV DL,DH
MOV AH,02H
INT 21H
H3:
MOV DL,BL ;还原DL中值
SHR DL,CL ;右移四位,取高四位
OR DL,30H ;与30H做或运算
CMP DL,30H
JZ H4
CMP DL,39H
JBE X3
ADD DL,7
X3:
MOV AH,02H
INT 21H
H4:
MOV DL,BL ;还原DL中值
AND DL,0FH ;取低四位
OR DL,30H
CMP DL,39H
JBE X4
ADD DL,7
X4:
MOV AH,02H
INT 21H
RECV2:
MOV DL,48H ;将字符H作为最后的后缀输出
INT 21H
POP DX
POP CX
POP BX
POP AX
RET
S2 ENDP
S3 PROC ;进行二进制的输出
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BX,SUM
MOV CX,16
E1:
SHL BX,1
MOV DL,30H
JNC N1
MOV DL,31H
N1:
MOV AH,02H
INT 21H
DEC CX
CMP CX,0
JZ RECV3
JMP E1
RECV3:
MOV DL,42H ;将字符B作为最后的后缀输出
INT 21H
POP DX
POP CX
POP BX
POP AX
RET
S3 ENDP
EXIT:
MOV AX,4C00H
INT 21H
CODE ENDS
END START