# 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!!!