Final review of assembly... really working hard to review...

The experiments the teacher asked us to do, I still feel grateful for them~

Let's talk about input and output, branching process, basic instructions, and then talk about the questions we have done.

## Input and Output#

### Convert the ASCII value of an integer to a numerical value#

- 0-9 30H-39H

Subtract 30H or AND with 1111(15) - A-F 41H-46H

Subtract 37H(55) - a-z 61H-66H

Subtract 57H(75)

### Input a single hexadecimal integer#

```
IN_1_HEX:
MOV AH, 01H
INT 21H ; The input value is stored in AL
CMP AL, '9' ; The input value is represented in memory as an ASCII value
JBE IN
SUB AL, 07H
IN:
SUB AL, 30H
```

### Input a two-digit hexadecimal integer#

The maximum value represented by a two-digit hexadecimal number is `FF`

, which is 255 and can be stored in eight bits.

```
IN_2_HEX:
CALL IN_1_HEX ; High-order hexadecimal -> AL
MOV AH, 10H
MUL AH
MOV AH, AL
CALL IN_1_HEX ; Low-order hexadecimal -> AL
ADD AL, AH
```

### Input a single decimal integer#

Remember to protect the previous data when using it, first PUSH and then POP

```
IN_1_DEC:
MOV AH, 01H ; AL
INT 21H
SUB AL, 30H
```

### Input a two-digit decimal integer#

```
IN_2_DEC:
CALL IN_1_DEC
MOV AH, 10 ; In hexadecimal, it is 10H
MUL AH
MOV AH, AL
CALL IN_1_DEC
ADD AL, AH
```

### Output a single hexadecimal integer#

```
DISP_1_HEX:
CMP DL, 09H
JBE L1
ADD DL, 07H
L1:
ADD DL, 30H
MOV AH, 02H
INT 21H
```

### Output a two-digit hexadecimal integer#

```
DISP_2_HEX:
MOV AL, DL
MOV AH, 0
MOV DL, 10H
DIV DL ; Divisor is 8 bits, AL stores quotient, AH stores remainder
MOV DL, AL
CALL DISP_1_HEX
MOV DL, AH
CALL DISP_1_HEX
```

### Output a single decimal integer#

```
DISP_1_DEC:
PUSH AX
ADD DL,30H
MOV AH,02H
INT 21H
POP AX
RET
```

### Output a two-digit decimal integer#

```
DISP_2_DEC: ; DL is divided by ten and the remainder is taken
PUSH AX
MOV AL,DL
MOV AH,0
MOV DL,10
DIV DL ; Divisor is 8 bits, AL stores quotient, AH stores remainder
MOV DL,AL
CALL DISP_1_DEC
MOV DL,AH
CALL DISP_1_DEC
POP AX
RET
```

### Output a multi-digit decimal integer with a sign bit#

```
DISP: ; Output the number in AX in decimal
PUSHF
PUSH DX
PUSH AX
PUSH BX
PUSH CX
MOV CX, 0
MOV BX, 10 ; Divided by 10
TEST AX, 8000H ; Check if the first bit of AX is 1 or 0
JE DISP1 ; If the result of the previous instruction is 0, jump
CALL FF ; Output negative sign
NEG AX ; Negate +1
DISP1:
MOV DX, 0
DIV BX ; Divisor is 16 bits, AX stores quotient, DX stores remainder
PUSH DX
INC CX
OR AX, AX ; Whether the quotient is complete
JNE DISP1 ; If not complete, continue to divide
DISP2:
POP DX
ADD DL, 30H ; Output as ASCII code
MOV AH, 02H
INT 21H
LOOP DISP2
POP CX
POP BX
POP AX
POP DX
POPF
RET
FF:
PUSH DX
PUSH AX
MOV DL, '-'
MOV AH, 02H
INT 21H
POP AX
POP DX
RET
```

## Loop and Branching Structure#

### Comparison#

The most important thing is comparison,

`TEST`

, `AND`

, `CMP`

, `SUB`

, and so on... can all be used for comparison.

#### TEST Instruction#

Instruction format: `TEST DST, SRC`

The `TEST`

instruction can be used to check if a bit is 1, because it is essentially an AND operation, that is, `DST & SRC`

, but it does not change the source operand and the destination operand.

For example, the result of `00010000 & X`

represents whether the fifth bit from the right of X is 1. If the result is 0, it means that this bit is 0, otherwise it is 1.

#### CMP Instruction#

Instruction format: `CMP DST, SRC`

It can compare the sizes of two numbers, which is essentially a subtraction operation, that is, `DST - SRC`

, but it does not change the source operand and the destination operand.

### Jump Instructions#

Here is to determine the specific size of the two numbers being compared and decide which statement to execute.

In C-style languages, it is like this:

```
if (a > b){
// Execute here if a > b
}else{
// Execute here if a <= b
}
```

In assembly language, it is:

```
CMP AX, BX
JA AGB
# Execute here if AX <= BX
AGB:
# Execute here if AX > BX
```

The `JA`

above is a jump instruction, and I won't go into detail about various instructions, read the book~

Here are a few important ones to remember~

- JE Two numbers are equal
- JNE Two numbers are not equal
- JA Unsigned, the former is greater than the latter

This is how I remember it: A is the first number among the two numbers being compared, B is the second number, so`JA`

means the first one is greater. - JG Signed comparison, the former is greater than the latter

G means greater than - JB Unsigned, the former is less than the latter
- JL Signed comparison, the former is less than the latter

L = less than - JAE Unsigned, the former is greater than or equal to the latter
- JGE Signed, the former is greater than or equal to the latter
- JBE Unsigned, the former is less than or equal to the latter
- JLE Signed, the former is less than or equal to the latter

### Binary to Hexadecimal Conversion#

We all know that one hexadecimal digit can represent four binary digits, so to convert binary to hexadecimal, we need to convert every four digits.

The general process is as follows

```
digraph g {
Shift left four bits of binary
-> Take the low four bits
-> "Low four bits + 30H"
-> Output the low four bits;
Output the low four bits -> Shift left four bits of binary [label="If the number of digits is not 0"]
}
```

### Control Transfer Instructions#

In the book P85

## Questions#

### Input a twenty-digit signed hexadecimal number, sort it, and output the maximum decimal number, minimum decimal number, second maximum decimal number, and second minimum decimal number#

```
DATA SEGMENT
X DW 20 DUP(?)
NUM DW 6
DATA ENDS
S1 SEGMENT PARA STACK
BUF1 DW 20H DUP (0)
LEN1 EQU $-BUF1
S1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:S1
GO:
MOV AX,DATA
MOV DS,AX
MOV AX,S1
MOV SS,AX
MOV SP,LEN1
MOV CX,NUM
MOV SI,OFFSET X
L1:
CALL IN_2_HEX
MOV AH, AL
CALL IN_2_HEX
MOV [SI],AX
CC:
CALL SPACE
ADD SI,2
LOOP L1
CALL HR
MOV CX,NUM
MOV SI,OFFSET X
DEC CX
LOOP1:
PUSH CX
MOV BX,OFFSET X
LOOP2:
MOV AX,[BX]
CMP AX,[BX+2]
JGE CONTINUE ; Signed comparison
XCHG AX,[BX+2]
MOV [BX],AX
CONTINUE:
ADD BX,2
LOOP LOOP2
POP CX
LOOP LOOP1
MOV cx, NUM
MOV si,offset X
CALL HR
dispdec2:
MOV AX,[si]
call DISP
call SPACE
add si,2
loop dispdec2
CALL HR
MOV si,offset X
CALL HR
; Minimum number
DEC NUM
SHL NUM, 1
ADD SI,NUM
MOV AX,[SI]
call DISP
call SPACE
; Maximum number
MOV si,offset X
MOV AX,[si]
call DISP
call SPACE
; Second minimum number
ADD SI,NUM
MOV AX,[SI-2]
call DISP
call SPACE
; Second maximum number
MOV si,offset X
MOV AX,[SI+2]
call DISP
call HR
MOV AH,4CH
INT 21H
IN_2_HEX:
PUSHF
PUSH BX
MOV BH,AH
CALL IN_1_HEX ;AL high
MOV AH,10H
MUL AH ;
MOV AH,AL
CALL IN_1_HEX ;AL low
ADD AL,AH
MOV AH,BH
POP BX
POPF
RET
IN_1_HEX:
PUSHF
PUSH BX
MOV BH,AH
MOV AH,01H
INT 21H
cmp AL,'9'
JBE IN_B
SUB AL,07H
IN_B: ; 'A-F'
SUB AL,30H
MOV AH,BH
POP BX
POPF
RET
DISP:
PUSHF
PUSH DX
PUSH AX
PUSH BX
PUSH CX
MOV CX,0
MOV BX,10
test AX,8000H;Whether it is negative
JE DISP1
CALL FF
;AND AX,7FFFH
NEG AX
DISP1:
MOV DX,0
DIV BX ;AX, quotient; DX, remainder
PUSH DX
INC CX
OR AX,AX ;Whether the quotient is 0
JNE DISP1
DISP2:
MOV AH,2
POP DX
ADD DL,30H
INT 21H
LOOP DISP2
POP CX
POP BX
POP AX
POP DX
POPF
RET
SPACE:
PUSH DX
PUSH AX
MOV DL,20H
MOV AH,02H
INT 21H
POP AX
POP DX
RET
HR:
PUSH AX
PUSH DX
MOV AH,02H
MOV DL,0AH
INT 21H
MOV DL,0DH
INT 21H
POP DX
POP AX
RET
FF:
PUSH DX
PUSH AX
MOV DL,'-'
MOV AH,02H
INT 21H
POP AX
POP DX
RET
CODE ENDS
END GO
```