# 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
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
JMP LOOPTWO

OUT0:
MOV AH,02H
MOV DL,'0'
INT 21H
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
JMP LOOP3

NEXT:
MOV CX,SI
SUB SI,1

LOOP4:
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
LOOP LOOPM
T:
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
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
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
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
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
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
LOOP LOOPM
T:
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
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:
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