Assembly (receive several N-digit decimal values (0 ~ 65535) from the keyboard and display their sum in binary, decimal and hexadecimal number systems.)

Keywords: Assembly Language security

subject

Receive several N-digit decimal values (0 ~ 65535) from the keyboard and display their sum in binary, decimal and hexadecimal number systems.
requirement:
(1) A subroutine is used to realize the input of an N-digit decimal value in the loop structure of the main program
The subroutine is called.
(2) When the user enters directly without entering a value, the input is ended;
(3) The output data is multi bit decimal data, and the sum calculated inside the machine is in hexadecimal form, which requires number system conversion, and then the result is output in the form of decimal string;
(4) Necessary prompt information is required in the program.

Running example

code

DATA SEGMENT
	STR1 DB "Please input a number: $"
	STR2 DB "The sum is: $"
	CRLF DB 0AH,0DH,'$'   ;Line feed
	COUNT DW 0   ;Save all input true and false
	DIVNUM DW 10  
	DIVNUM1 DW 16
	MULNUM DW 10
	RESULT DB 5 DUP(?)
	RESULT1 DB 5 DUP(?)
	KONGGE DB 32,32,32,32,32,32,32,32,32,32,32,32,'$' ;Output multiple spaces for alignment
	TEMP DW ?
	ARRAY DB '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' ;When used to output hexadecimal form, it is compared with subscript
DATA ENDS
CODE SEGMENT 
ASSUME CS:CODE,DS:DATA
START:
	MOV AX,DATA
	MOV DS,AX
	
LOOP1:
	CALL GET
	CMP CX,0
	JZ ENDINPUT
	ADD COUNT,BX
	JMP LOOP1
	
ENDINPUT:
	LEA DX,CRLF
	MOV AH,9
	INT 21H
	
	LEA DX,STR2
	MOV AH,9
	INT 21H

TWO:
	MOV BX,COUNT
	MOV TEMP,0
LOOPTWO:
	CMP TEMP,16
	JZ TEN
	SAL BX,1
	JNC OUT0
	MOV AH,02H
	MOV DL,'1'
	INT 21H
	ADD TEMP,1
	JMP LOOPTWO
	
OUT0:
	MOV AH,02H
	MOV DL,'0'
	INT 21H
	ADD TEMP,1
	JMP LOOPTWO

	
TEN:
	MOV AH,02H
	MOV DL,'B'
	INT 21H
	
	LEA DX,CRLF
	MOV AH,9
	INT 21H
	
	LEA DX,KONGGE
	MOV AH,9
	INT 21H
	
	MOV AX,COUNT
	MOV SI,0
	MOV DX,0
LOOP3:
	DIV DIVNUM; AX...DX
	MOV RESULT[SI],DL   ;Because the remainder is less than 10, so DH=0
	CMP AX,0
	JZ NEXT
	MOV DX,0
	ADD SI,1
	JMP LOOP3
	
NEXT:	
	ADD SI,1
	MOV CX,SI
	SUB SI,1

LOOP4:
	ADD RESULT[SI],30H
	MOV AH,02H
	MOV DL,RESULT[SI]
	INT 21H
	SUB SI,1
	LOOP LOOP4
	
	
	MOV AH,02H
	MOV DL,'D'
	INT 21H
	
	LEA DX,CRLF
	MOV AH,9
	INT 21H
	
	LEA DX,KONGGE
	MOV AH,9
	INT 21H
	
	
SIXTEEN:	
	MOV AX,COUNT
	MOV CX,4
	MOV SI,0
	MOV DX,0
LOOPM:
	DIV DIVNUM1; AX....DX
	MOV RESULT1[SI],DL   ;Although the remainder is placed in DX Li, but the remainder won't exceed fifteen, so DH Is 0
	CMP AX,0
	JZ T
	MOV DX,0
	ADD SI,1
	LOOP LOOPM
T:	
	ADD SI,1
	MOV CX,SI
	SUB SI,1
	
LOOP5:
	MOV BL,RESULT1[SI]
	MOV BH,0
	MOV DI,BX
	
	MOV AH,02H
	MOV DL,ARRAY[DI]
	INT 21H
	SUB SI,1
	LOOP LOOP5
	

	MOV AH,02H
	MOV DL,'H'
	INT 21H
	
	LEA DX,CRLF
	MOV AH,9
	INT 21H
	
	
	MOV AX,4C00H
	INT 21H
	
GET PROC ;No input value, no output, but store the results in BX in
	LEA DX,STR1
	MOV AH,9
	INT 21H
	
	MOV CX,0;CX It is used to count and judge whether this input only enters the carriage return
	MOV BX,0;use BX Save the last true value of the entered number
LOOPT:
	MOV AH,1
	INT 21H
	
	CMP AL,0DH
	JZ OVER
	
	MOV CX,1
	MOV AH,0
	SUB AL,30H
	ADD AX,BX
	MUL MULNUM;DW Type and DW Multiply the types, and put the upper 16 bits in DX The 16th place in the AX
	MOV BX,AX
	JMP LOOPT
	
OVER:
	MOV AX,BX
	DIV DIVNUM
	MOV BX,AX
	RET
GET ENDP
		
CODE ENDS
END START

explain

1. Input part

LOOP1:
	CALL GET
	CMP CX,0
	JZ ENDINPUT
	ADD COUNT,BX ;Every time the real NUM Add to COUNT in
	JMP LOOP1
	
ENDINPUT:
	LEA DX,CRLF;Line feed
	MOV AH,9
	INT 21H
	
	LEA DX,STR2;output The sum is:
	MOV AH,9
	INT 21H
GET PROC ;No input value, no output, but store the results in BX in
	LEA DX,STR1
	MOV AH,9
	INT 21H
	
	MOV CX,0;CX It is used to count and judge whether this input only enters the carriage return
	MOV BX,0;use BX Save the last true value of the entered number
LOOPT:
	MOV AH,1
	INT 21H
	
	CMP AL,0DH
	JZ OVER
	
	MOV CX,1
	MOV AH,0
	SUB AL,30H
	ADD AX,BX
	MUL MULNUM;DW Type and DW Multiply the types, and put the upper 16 bits in DX The 16th place in the AX
	MOV BX,AX
	JMP LOOPT
	
OVER:
	MOV AX,BX
	DIV DIVNUM
	MOV BX,AX
	RET
GET ENDP
Overall thought

The difference between this question and the previous one is that the number entered is not a single decimal (0 ~ 9)
Here, I use to receive a character input by the user. For example, input 6552, receive the first character 6, multiply 6 by 10, and put it in a register BX; then receive 5, and BX+5, then the value in BX is 65, and then multiply BX by 10 (the multiplication of 10 and subsequent multiplication here use AX) After receiving 5, BX+5, then the value in BX is 655, and then BX is multiplied by 10; after receiving 2, BX+2, now BX is 6552, and BX is multiplied by 10,
Because I am

MOV AX,BX
MUL MULNUM  
MOV BX,AX

(if it does not exceed 65535 after multiplying by 10, DX will not be used). Now the value in DX:AX is 65520. Now that it has been received, enter, exit the cycle of input characters, and divide DX:AX by 10

Step by step explanation
LOOP1:
	CALL GET
	CMP CX,0
	JZ ENDINPUT
	ADD COUNT,BX
	JMP LOOP1

First, a loop CALL GET
Look at the GET subroutine

	LEA DX,STR1
	MOV AH,9
	INT 21H
	
	MOV CX,0;CX It is used to count and judge whether this input only enters the carriage return
	MOV BX,0;use BX Save the last true value of the entered number

Output STR1. Here I use CX as the judgment, because if the user only enters one carriage return, it means that the user has finished the whole input part. If the user enters 6553 and then enters carriage return, it means that the user only ends this input and will continue to enter the next number. Therefore, I use CX to judge whether other numbers are entered before carriage return

LOOPT:
	MOV AH,1 ;User input character
	INT 21H
	
	CMP AL,0DH ;Judge whether to enter or not. If yes, exit the cycle, which is the only condition for exiting the cycle
	JZ OVER
	
	MOV CX,1 ;Not enter, it proves that there are numbers entered now, so CX For 1, the next time the user will enter a complete NUM
	MOV AH,0
	SUB AL,30H ;AX Saves the true value of the input character
	ADD AX,BX ;
	MUL MULNUM;DW Type and DW Multiply the types, and put the upper 16 bits in DX The 16th place in the AX
	MOV BX,AX
	JMP LOOPT
	
OVER:
	MOV AX,BX
	DIV DIVNUM
	MOV BX,AX

Look at the notes, and it has been made clear in the overall thought just now

2. Output hex

Take the output hexadecimal as an example
In fact, the output part is quite simple

SIXTEEN:	
	MOV AX,COUNT;Assign and to AX
	MOV CX,4;Give Way CX It is 4 as the number of cycles. Because it is 16 bits, it is 4 bits when converted to hexadecimal
	MOV SI,0 ;Used as an index register as a pointer
	MOV DX,0 
LOOPM:
	DIV DIVNUM1; AX....DX
	MOV RESULT1[SI],DL   ;Although the remainder is placed in DX Li, but the remainder won't exceed fifteen, so DH Is 0
	CMP AX,0
	JZ T
	MOV DX,0
	ADD SI,1
	LOOP LOOPM
T:	
	ADD SI,1
	MOV CX,SI
	SUB SI,1
	
LOOP5:
	MOV BL,RESULT1[SI]
	MOV BH,0
	MOV DI,BX
	
	MOV AH,02H
	MOV DL,ARRAY[DI]
	INT 21H
	SUB SI,1
	LOOP LOOP5
	

	MOV AH,02H
	MOV DL,'H'
	INT 21H
Step by step explanation
LOOPM:
	DIV DIVNUM1; AX....DX
	MOV RESULT1[SI],DL   ;Although the remainder is placed in DX Li, but the remainder won't exceed fifteen, so DH Is 0
	CMP AX,0
	JZ T
	MOV DX,0
	ADD SI,1
	LOOP LOOPM

During DIV DIVNUM1, it should be noted that when the divisor is DX type, the divisor is DX:AX by default, the quotient is placed in AX, and the remainder is placed in DX; when the divisor is DB type, the divisor is AX by default, the quotient is placed in AL, and the remainder is placed in AH. So why should the divisor be DW type? For example, after 6552 is divided by 10, the quotient is 655, the remainder is 2, AL is 8 bits, and 655 is out of range, which means that There will be an error. So use the divisor of DW type
Loop remainder and put it in an array
If ax (AX saves the quotient) is 0, it proves that it has all been played. If it is not, you can exit the cycle and output the hexadecimal part.
Pay attention to MOV DX,0 at the end of each cycle, because DX will be the high-order divisor for a while, and the remainder was also placed in DX just now

T:	
	ADD SI,1
	MOV CX,SI ;CX As the number of cycles, it is equal to the subscript of the last number of the array plus 1
	SUB SI,1
	
LOOP5:
	MOV BL,RESULT1[SI]
	MOV BH,0
	MOV DI,BX
	
	MOV AH,02H
	MOV DL,ARRAY[DI]
	INT 21H
	SUB SI,1
	LOOP LOOP5
	

	MOV AH,02H
	MOV DL,'H'
	INT 21H

Output in reverse order without difficulty

If there are mistakes, welcome to correct ah, thank you for watching!!!

Posted by MiniMonty on Sun, 05 Dec 2021 01:50:26 -0800