Final review compilation... Really working hard on the review...

The experiments assigned by the lab instructor, I feel grateful for them~

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

## Input/Output

### Converting ASCII code value of an integer to 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 code value
JBE IN
SUB AL, 07H
IN:
SUB AL, 30H
```

### Input a two-digit hexadecimal integer

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

, which is 255, and it 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 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, this 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, quotient is stored in AL, remainder in AH
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 division by ten
PUSH AX
MOV AL,DL
MOV AH,0
MOV DL,10
DIV DL ; Divisor is 8 bits, quotient is stored in AL, remainder in AH
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 ; Divisor is 10
TEST AX, 8000H ; Check if the most significant bit of AX is 1 or 0
JE DISP1 ; If the result of the previous instruction is 0, jump
CALL FF ; Output the negative sign
NEG AX ; Negate +1
DISP1:
MOV DX, 0
DIV BX ; Divisor is 16-bit, quotient in AX, remainder in DX
PUSH DX
INC CX
OR AX, AX ; Check if quotient is 0
JNE DISP1 ; If not 0, continue division
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 particular bit is 1, as it essentially performs an AND operation, i.e., `DST & SRC`

, without modifying the source and destination operands.

For example, the result of `00010000 & X`

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

#### CMP Instruction

Instruction format: `CMP DST, SRC`

It can be used to compare the sizes of two numbers, essentially performing a subtraction operation, i.e., `DST - SRC`

, without modifying the source and destination operands.

### Jump Instructions

Here, we determine the specific comparison of the two numbers being compared and decide which statement to execute.

In C-style languages, it would be like this:

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

In assembly language, it would be:

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

The `JA`

above is a jump instruction. I won't go into detail about various instructions, refer to the book~

Here are a few important ones to remember~

- JE Two numbers are equal
- JNE Two numbers are not equal
- JA Unsigned, first number is greater than second number

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

means the first number is greater. - JG Signed comparison, first number is greater than second number

G stands for greater than - JB Unsigned, first number is less than second number
- JL Signed comparison, first number is less than second number

L stands for less than - JAE Unsigned, first number is greater than or equal to second number
- JGE Signed, first number is greater than or equal to second number
- JBE Unsigned, first number is less than or equal to second number
- JLE Signed, first number is less than or equal to second number

### 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 four digits at a time.

The general process is as follows:

```
digraph g {
Shift left four binary digits
-> Take the low four digits
-> "Low four digits + 30H"
-> Output the low four digits;
Output the low four digits -> Shift left four binary digits [label="If there are more digits"]
}
```

### Control Transfer Instructions

Refer to page 85 of the book

## Questions

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

```
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; Check if 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 ; Check if 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
```