题目
从键盘接收若干个一位十进制数值(0-9),并以十进制数据形式显示其和。
要求:
1)用子程序实现一位十进制数值的输入
2)当用户未输入数值,直接回车时,结束输入
3)输入的数据为多位十进制数据,而机器内部计算的和是十六进制形式,需要进行数值转换,然后以字符串形式输出结果
4)程序中要求有必要的提示信息
示例:用户在提示信息下输入三个数值
Please input a number: 5
Please input a number: 3
Please input a number: 4
Please input a number: (用户此时按下回车)
The sum is:12
代码
DATA SEGMENT
STR1 DB "Please input a number: $"
STR2 DB "The sum is: $"
CRLF DB 0AH,0DH,'$' ;换行
COUNT DB 0
DIVNUM DB 10
RESULT DB 0,0,0,0,0,0,0,0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
LOOP1:
CALL INPUT ;子程序调用
CMP AL,0DH
JZ ENDINPUT
SUB AL,30H
ADD COUNT,AL
LEA DX,CRLF ;换行
MOV AH,9
INT 21H
JMP LOOP1
ENDINPUT:
LEA DX,STR2 ;换行
MOV AH,9
INT 21H
MOV AL,COUNT
MOV AH,0 ;使AX=AL作为被除数
MOV SI,0
LOOP2:
DIV DIVNUM ; AL......AH
;ADD AH,30H
MOV RESULT[SI],AH
CMP AL,0
JZ NEXT
MOV AH,0
ADD SI,1
JMP LOOP2
NEXT:
ADD SI,1
MOV CX,SI
SUB SI,1
LOOP3:
ADD RESULT[SI],30H
MOV AH,02H
MOV DL,RESULT[SI]
INT 21H
SUB SI,1
LOOP LOOP3
MOV AX,4C00H
INT 21H
INPUT PROC
LEA DX,STR1
MOV AH,9
INT 21H
MOV AH,1
INT 21H
RET
INPUT ENDP
CODE ENDS
END START
解释
1、
LOOP1:
CALL INPUT ;子程序调用
CMP AL,0DH
JZ ENDINPUT
SUB AL,30H
ADD COUNT,AL
LEA DX,CRLF
MOV AH,9
INT 21H
JMP LOOP1
循环,但是是用JMP进行的,因为你不知道循环的次数,而最后是根据输入回车来跳出循环的,所以可以不使用LOOP指令(这个循环只有一个出口,就是输入回车的时候)
子程序调用CALL INPUT
INPUT PROC
LEA DX,STR1
MOV AH,9
INT 21H
MOV AH,1
INT 21H
RET
逻辑很简单显示提示信息STR1,然后输入数据
这里不需要进行寄存器保护,因为CALL指令是第一个代码,且子程序中也并未改变什么需要的寄存器
CMP AL,0DH
因为子程序调用中输入的字符会保存在AL中,比较AL和回车的ASCII吗,如果是回车,则循环结束,跳入的ENDINPUT
否则将AL-30H,将字符的ASCII转换成真实的值,用COUNT来保存累加和
2、
ENDINPUT:
LEA DX,STR2 ;换行
MOV AH,9
INT 21H
MOV AL,COUNT
MOV AH,0 ;使AX=AL作为被除数
MOV SI,0
LOOP2:
DIV DIVNUM ; AL......AH
;ADD AH,30H
MOV RESULT[SI],AH
CMP AL,0
JZ NEXT
MOV AH,0
ADD SI,1
JMP LOOP2
现在所有输入的数值的真实的和已经拿到了,保存在COUNT中,接下来就是将COUNT逐个模10,依次拿到COUNT中的每一位数,然后保存在数组RESULT中,因为模10最先拿到的是个位,十位…,最后需要将数组RESULT逆向输出
MOV AL,COUNT
MOV AH,0 ;使AX=AL作为被除数
MOV SI,0
被除数默认为AX,因为COUNT是DB类型的,所以将COUNT的值赋给AX,这里用SI来控制一会数值存放在RESULT数组中的位置
LOOP2:
DIV DIVNUM ; AL......AH
;ADD AH,30H
MOV RESULT[SI],AH
CMP AL,0
JZ NEXT
MOV AH,0
ADD SI,1
JMP LOOP2
除10取余,现在数组中保存的是数的真实值(不是ASCII值,后面输出的时候要加上30H,我觉得现在加应该也可以,但是我在这里加的时候出错了,索性直接在最后加了)
判断AL是否为0,如果AL为0,证明所有COUNT的每一位都放进数组了,退出循环即可。如果没有继续循环,SI+1,下一个数放在数组的下一位,记得要将AH赋0,除数是AX
3、
NEXT:
ADD SI,1
MOV CX,SI
SUB SI,1
LOOP3:
ADD RESULT[SI],30H
MOV AH,02H
MOV DL,RESULT[SI]
INT 21H
SUB SI,1
LOOP LOOP3
最后一步输出数组中的数即可
ADD SI,1
MOV CX,SI
SUB SI,1
因为现在SI为数组最后一位的下标,需要+1才为数组的长度,赋值给CX作为循环次数
LOOP3:
ADD RESULT[SI],30H
MOV AH,02H
MOV DL,RESULT[SI]
INT 21H
SUB SI,1
LOOP LOOP3
逆向输出数组即可
😆下次还有个进阶版的,感谢你的观看,如果有错误的话,还望指正