野声

Hey, 野声!

谁有天大力气可以拎着自己飞呀
twitter
github

IBM-PC Assembly Language Programming Review

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
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.