期末復習彙編... 真的是好努力的復習...
實驗老師讓我們做的那幾個實驗,想想還覺得謝謝了~
談一下輸入輸出、分支流程、基本指令,再談一下做過的幾個題目。
輸入輸出#
整數的 ASCII 碼值轉為數值#
- 0-9 30H-39H
可以減去 30H 或者 與上 1111 (15) - A-F 41H-46H
減去 37H (55) - a-z 61H-66H
減去 57H (75)
輸入一位十六進制整數#
IN_1_HEX:
MOV AH, 01H
INT 21H ;輸入的值存在AL裡
CMP AL, '9' ;輸入的值在內存中都是以ASCII碼的值表示
JBE IN
SUB AL, 07H
IN:
SUB AL, 30H
輸入兩位十六進制整數#
兩位十六進制表示的值最多是 FF
,也就是 255,用八位就可以存下。
IN_2_HEX:
CALL IN_1_HEX ;高位十六進制->AL
MOV AH, 10H
MUL AH
MOV AH, AL
CALL IN_1_HEX ;低位十六進制->AL
ADD AL, AH
輸入一位十進制整數#
實際使用的時候記得要保護之前的數據,先 PUSH 再 POP
IN_1_DEC:
MOV AH, 01H ;AL
INT 21H
SUB AL, 30H
輸入兩位十進制整數#
IN_2_DEC:
CALL IN_1_DEC
MOV AH, 10 ; 十六進制這裡為10H
MUL AH
MOV AH, AL
CALL IN_1_DEC
ADD AL, AH
輸出一位十六進制整數#
DISP_1_HEX:
CMP DL, 09H
JBE L1
ADD DL, 07H
L1:
ADD DL, 30H
MOV AH, 02H
INT 21H
輸出兩位十六進制整數#
DISP_2_HEX:
MOV AL, DL
MOV AH, 0
MOV DL, 10H
DIV DL ; 除數是 8 位 AL 存商, AH 存餘數
MOV DL, AL
CALL DISP_1_HEX
MOV DL, AH
CALL DISP_1_HEX
輸出一位十進制整數#
DISP_1_DEC:
PUSH AX
ADD DL,30H
MOV AH,02H
INT 21H
POP AX
RET
輸出兩位十進制整數#
DISP_2_DEC: ; DL 除十取餘法
PUSH AX
MOV AL,DL
MOV AH,0
MOV DL,10
DIV DL ; 除數是 8 位 AL 存商, AH 存餘數
MOV DL,AL
CALL DISP_1_DEC
MOV DL,AH
CALL DISP_1_DEC
POP AX
RET
帶符號位的輸出多位十進制整數#
DISP: ; 用十進制出AX中的數
PUSHF
PUSH DX
PUSH AX
PUSH BX
PUSH CX
MOV CX, 0
MOV BX, 10 ; 除 10 取餘法
TEST AX, 8000H ; 檢測AX首位是1還是0
JE DISP1 ; 如果上一句的結果為0,就跳
CALL FF ; 輸出負號
NEG AX ; 取反+1
DISP1:
MOV DX, 0
DIV BX ;除數是 16 位 AX,商;DX,餘數
PUSH DX
INC CX
OR AX, AX ; 是否商完
JNE DISP1 ; 沒商完繼續商
DISP2:
POP DX
ADD DL, 30H ; 以ascii碼輸出
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
循環分支結構#
比較#
最重要的就是 比較,
TEST
,AND
,CMP
,SUB
還有等等等等... 都可以拿來做比較。
TEST 指令#
指令格式:TEST DST, SRC
TEST
指令可以被用來檢測某一位是否為 1,因為其本質就是與運算,也就是 DST & SRC
,但是不改變源操作數和目標操作數。
如 00010000 & X
的結果就表示 X 的倒數第五位是否為 1,要是與出來為 0,就說明這一位為 0,否則為 1。
CMP 指令#
指令格式:CMP DST, SRC
可以比較兩個數的大小,本質就是減法運算,也就是 DST - SRC
,但是不改變源操作數和目標操作數。
跳轉指令#
這裡的就是判斷被比較的兩個數的具體大小,然後決定執行哪一句。
C-style 的語言中是這樣:
if (a > b){
// a > b 的話執行這兒
}else{
// a <= b 的話執行這兒
}
匯編中呢,就是:
CMP AX, BX
JA AGB
# AX <= BX 的話執行這兒
AGB:
# AX > BX 的話執行這兒
上面的 JA
就是一個跳轉指令,再詳細的各種指令我就不說了,看書~
下面稍微說幾個記得牢的~
- JE 兩個數相等
- JNE 兩個數不相等
- JA 無符號 前者大於後者
我是這樣記得, A 就是兩個比較的數裡前面那個,B 就是兩個比較的數裡後面那個,所以JA
就是前面的大。 - JG 有符號比較,前者大於後者
G 的意思就是 greater than - JB 無符號 前者小於後者
- JL 有符號比較 前者小於後者
L = less than - JAE 無符號大於等於
- JGE 有符號大於等於
- JBE 無符號小於等於
- JLE 有符號小於等於
二進制轉十六進制#
我們都知道,一位十六進制可以表示四位二進制,所以要把二進制轉為十六進制的話,得每四位每四位的轉換。
大概流程如下
digraph g {
循環左移四位二進制
-> 取低四位
-> "低四位+30H"
-> 輸出低四位;
輸出低四位 ->循環左移四位二進制 [label="如果位數不為0"]
}
控制轉移指令#
書上 P85
題目#
輸入二十位帶符號十六進制數,排序後輸出十進制最大數、最小數、次大數、次小數#
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 ;有符號比較
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
; 最小數
DEC NUM
SHL NUM, 1
ADD SI,NUM
MOV AX,[SI]
call DISP
call SPACE
; 最大數
MOV si,offset X
MOV AX,[si]
call DISP
call SPACE
; 次小數
ADD SI,NUM
MOV AX,[SI-2]
call DISP
call SPACE
; 次大數
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;是否為負
JE DISP1
CALL FF
;AND AX,7FFFH
NEG AX
DISP1:
MOV DX,0
DIV BX ;AX,商;DX,餘數
PUSH DX
INC CX
OR AX,AX ;是否為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