彙整自個人OneNote筆記。

指令格式

標號:   指令助記符 目的操作數, 源操作數 ; 註釋

數據傳送類指令

重點掌握:MOV XCHG XLAT PUSH POP LEA

通用數據傳送指令

傳送指令 MOV


mov     byte ptr [si], 0ah  ; ds:[si]←0ah,字節操作
mov     word ptr [si+2], 0bh; ds:[si+2]←0bh,字操作

交換指令 XCHG


xchg    reg, reg/mem        ; reg←→reg/mem,也可寫做xchg reg/mem, reg

換碼指令 XLAT


xlat                        ; al←ds:[bx+al]

堆棧操作指令


push/pop r16

進棧指令 PUSH

使SP減2,把一個字操作數存入棧頂。

出棧指令 POP

把一個字操作數傳送至目的操作數,使SP加2。

標誌傳送指令

標誌寄存器傳送指令傳送FLAGS的內容;標誌位操作指令對CF DF IF標誌復位或置位。

標誌寄存器傳送 LAHF SAHF PUSHF POPF


lahf                        ; AH←FLAGS的低字節
sahf                        ; FLAGS的低字節←AH
;(上兩條指令,除AH的第7/6/2/4/0位外任意)
pushf                       ; SP←SP-2,SS:[SP]←FLAGS
popf                        ; FLAGS←SS:[SP],SP←SP+2

標誌位操作 CLC STC CMC CLD STD CLI STI

CF/DF/IF標誌復位或置位。
CL:復位爲0
ST:置位爲1
CM:求反

  • 任意設置進位標誌:CLC STC CMC

  • 串操作指令:CLD STD

  • 編寫中斷服務程序時,禁止/允許可屏蔽中斷:CLI STI

地址傳送指令

有效地址傳送指令 LEA


lea     r16, mem            ; r16←mem的有效地址

指針傳送指令 LDS LES


lds     r16, mem            ; r16←mem,ds←mem+2
les     r16, mem            ; r16←mem,es←mem+2

輸入輸出指令

與外設進行數據交換。
外設:端口(Port)即I/O地址

輸入指令 IN

輸出指令 OUT

算術運算類指令

重點:ADD/ADC/INC SUB/SBB/DEC CBW/CWD

加法指令

加法指令 ADD

帶進位加法指令 ADC

主要與ADD配合,實現多精度加法。


adc     dest, src               ; dest←dest+src+cf

增量指令 INC

減法指令

參考對應的加法指令。

減法指令 SUB

帶借位減法指令 SBB

減量指令 DEC

其他

求補指令 NEG

用0減去操作數,結果返回給操作數。
對標誌的影響與用0作減法的SUB指令一樣。


neg     reg/mem                 ; reg/mem←0-reg/mem

比較指令 CMP

執行的功能與SUB相似,但結果不回送至目的操作數。
配合Jcc

乘法指令

利用OFCF判斷乘積的高一半是否具有有效數值。

MUL:高一半爲0,則OF=CF=0;否則均爲1。

IMUL:高一半爲低一半的符號擴展,則OF=CF=0;否則均爲1。

無符號乘法 MUL


mul     r8/m8                   ; 無符號字節乘法,ax←al×r8/m8
mul     r16/m16                 ; 無符號字乘法,dx.ax←ax×r16/m16

有符號乘法 IMUL


imul     r8/m8                  ; 有符號字節乘法,ax←al×r8/m8
imul     r16/m16                ; 有符號字乘法,dx.ax←ax×r16/m16

除法指令

對標誌沒有定義。
會產生結果溢出(除法錯中斷,8086CPU編號爲0的內部中斷):

  • 除數爲0
  • 商超出範圍

無符號除法 DIV


div     r8/m8                   ; 無符號字節乘法,al←ax÷r8/m8的商,ah←ax÷r8/m8的餘數
div     r16/m16                 ; 無符號字乘法,ax←dx.ax÷r16/m16的商,dx←dx.ax÷r16/m16的餘數

有符號除法 IDIV


idiv     r8/m8                  ; 有符號字節乘法,al←ax÷r8/m8的商,ah←ax÷r8/m8的餘數
idiv     r16/m16                ; 有符號字乘法,ax←dx.ax÷r16/m16的商,dx←dx.ax÷r16/m16的餘數

符號擴展指令 CBW CWD

不影響標誌位,常用於獲得倍長的數據。
64H(表示十進制100)最高位$D_7$爲0,符號擴展後爲0064H(仍表示十進制100);FF00H(表示十進制-256)最高位$D_{15}$爲1,符號擴展後爲FFFFFF00H(仍表示十進制256)。
利用符號擴展指令可得到除法指令所需的倍長於除數的被除數。


cwd
idiv bx

對無符號除法:直接清零即可。

壓縮BCD碼加減調整指令DAA DAS

OF無定義,但影響其他標誌,比如CF


add/adc al, i8/r8/m8
daa                             ; 將al的加和調整爲壓縮BCD碼
sub/sub al, i8/r8/m8
das                             ; 將al的減差調整爲壓縮BCD碼

非壓縮BCD碼加減乘除調整指令AAA AAS AAM AAD


add/adc al, i8/r8/m8
aaa                             ; 將al的加和調整爲壓縮BCD碼
                                ; ah←ah+調整的進位
sub/sub al, i8/r8/m8
aas                             ; 將al的減差調整爲壓縮BCD碼
                                ; ah←ah-調整的借位
mul     r8/m8
aam                             ; 將ax的乘積調整爲非壓縮BCD碼
aad                             ; 將ax中非壓縮BCD碼調整爲二進制數
div     r8/m8

位操作類指令

邏輯運算指令

邏輯與 AND

皆1方爲1。


add     reg, imm/reg/mem
add     mem, imm/reg

CF=OF=0;SF ZF PF根據結果;AF未定義。
可用於復位(0相與,1變0)。

邏輯或 OR

皆0方爲0。
標誌位變化同AND
可用於置位(1相或,0變1)。

邏輯異或 XOR

不同方爲1。
標誌位變化同AND
可用於求反(1相異或,1變0,0變1);自身XOR則清零。

邏輯非 NOT

按位取反,不影響標誌位。

not     reg/mem

測試指令 TEST

類似AND,結果不返回至操作數。


test    al, 01h             ; 測試最後一位是否爲0(是則ZF=1)

移位指令

邏輯左移 SHL


shl     reg/mem, 1/cl       ; 邏輯左移1/cl位(最低位補0,最高位進入CF)

邏輯右移 SHR


shr     reg/mem, 1/cl       ; 邏輯右移1/cl位(最高位補0,最低位進入CF)

算術左移 SAL


sal     reg/mem, 1/cl       ; 算術左移1/cl位(同SHL)

算術右移 SAR


sar     reg/mem, 1/cl       ; 算術右移1/cl位(最高位不變,最低位進入CF)

小結

若最高位改變:OF=1

  • shl/sal 1位相當於無符號數乘2

  • shr 1位相當於無符號數除以2

  • sar 1位相當於有符號數除以2(與idiv有別)

    • 如-5(FBH)經SAR右移1位等於-3(FDH),但IDIV指令執行-5÷2結果爲-2

循環移位指令 ROL ROR RCL RCR


rol     reg/mem, 1/cl       ; 不帶進位循環左移  
ror     reg/mem, 1/cl       ; 不帶進位循環右移  
rcl     reg/mem, 1/cl       ; 帶進位循環左移  
rcr     reg/mem, 1/cl       ; 帶進位循環右移

控制轉移類指令

重點JMP JCC LOOP CALL RET INT n IRET 常用系統功能調用

CS:當前指令所在代碼段的段地址

IP:要執行的下一條指令的偏移地址

無條件轉移指令 JMP

段內轉移:

  • 近轉移(near):在當前代碼段64KB(±32KB)範圍內轉移。
  • 短轉移(short):在段內-128~127的範圍的轉移。

段間轉移:

  • 遠轉移(far):更改CS段地址和IP偏移地址。可在1MB範圍內轉移。目標地址用32位遠指針表示,即邏輯地址。

通常彙編程序根據位移量大小自動形成短轉移/近轉移/遠轉移指令。同時彙編程序也提供shortnear ptrfar ptr強制。

  • 段內轉移 相對尋址:jmp label ; ipip+位移量

  • 段內轉移 間接尋址:jmp r16/m16 ; ipr16/m16


jmp     ax
jmp     word ptr[2000h]
  • 段間轉移 直接尋址:jmp far ptr label ; iplabel的偏移地址,cslabel的段地址

  • 段間轉移 間接尋址:jmp far ptr mem ; ip[mem]cs[mem+2]

條件轉移指令 Jcc


jcc     label

判斷單個標誌位狀態

  • JZ/JEJNZ/JNE利用ZF,判斷結果是否爲0(或相等)

  • JSJNS利用SF,判斷結果正負

  • JOJNO利用OF,判斷結果是否溢出

  • JP/JPEJNP/JPO利用PF,判斷結果中1的個數奇偶

  • JC/JB/JNAEJNC/JNB/JAE利用CF,判斷結果是否進位/借位

比較無符號數高低

高(Above)、低(Below)。
利用CF確定高低,利用ZF確定相等。

  • JB/JNAE

  • JNB/JAE

  • JBE/JNA

  • JNBE/JA

比較有符號數大小

大(Greater)、小(Less)。
利用SFOF確定大小,利用ZF確定相等。

  • JL/JNGE

  • JNL/JGE

  • JLE/JNG

  • JNLE/JG

循環指令 LOOP


jcxz    label   ; cx=0則轉移到標號label
loop    label   ; cx←cx-1;cx≠0則轉移到label
loopz   label   ; cx←cx-1;cx≠0且zf=1則轉移到label
loopnz  label   ; cx←cx-1;cx≠0且zf=0則轉移到label

子程序指令 CALL RET

子程序調用指令 CALL


CALL    label           ; 段內調用 直接尋址
CALL    r16/m16         ; 段內調用 間接尋址
CALL    far ptr label   ; 段間調用 直接尋址
CALL    far ptr mem     ; 段間調用 間接尋址

CALL指令需要保存返回地址:

  • 段內調用:入棧偏移地址IP

    • SPSP-2,SS:[SP]IP
  • 段間調用:入棧偏移地址IP和段地址CS

    • SPSP-2,SS:[SP]IP
    • SPSP-2,SS:[SP]CS

子程序返回指令 RET


ret             ; 無參數段內返回
ret     i16     ; 有參數段內返回
ret             ; 無參數段間返回
ret     i16     ; 有參數段間返回

需要彈出CALL指令壓入堆棧的返回地址。

  • 段內返回:出棧偏移地址IP

    • IPSS:[SP]SPSP+2
  • 段间返回:出棧偏移地址IP和段地址CS

    • IPSS:[SP]SPSP+2
    • CSSS:[SP]SPSP+2

返回指令RET的參數


ret i16         ; SP←SP+i16

可以方便廢除執行CALL指令之前入棧的參數。

中斷指令 INT i8 IRET INTO

8086可管理256个中斷。

  • 外部中斷

    • 可屏蔽中斷:可由CPU中斷允许標誌IF控制
    • 非屏蔽中斷:不受CPU中斷允许標誌IF控制
  • 內部中斷

    • 除法錯中斷:溢出,0號中斷
    • 指令中斷:中斷調用指令 INT i8
    • 斷點中斷:斷點調試 INT 3
    • 溢出中斷:執行溢出中斷指令,OF=1產生的4號中斷
    • 單步中斷:TF=1在每條指令執行後產生的1號中斷

int     i8      ; 中斷調用(產生i8號中斷)
iret            ; 中斷返回
into            ; 溢出中斷指令:若OF=1,產生4號中斷,否則順序執行

系統功能調用

INT 21H,AH=02H 輸出字符

DL=字符的ASCII碼

INT 10H,AH=0EH 輸出字符

AL=字符的ASCII碼

BL=字符顏色值(圖形方式)

BH=頁號(字符方式)

(通常使BX=0)

INT 21H,AH=09H 輸出字符串

DS:DX=欲顯示字符串在主存中的首地址,以$(24H)結束

INT 21H,AH=01H 輸入字符

AL=字符的ASCII碼

INT 16H,AH=0 輸入字符

AX=鍵值代碼

標準ASCII碼按鍵:AL=ASCII碼,AH=掃描碼

INT 21H,AH=0AH 輸入字符串

DS:DX=緩衝區首地址

緩衝區的定義

  • 第1字節:最多欲接收的字符個數(1-255,含回車)
  • 第2字節:實際輸入的字符個數
  • 第3字節開始:輸入的字符串

INT 21H,AH=0BH 按鍵判斷

AL=0,當前沒有按鍵;

AL=FFH,當前已經按鍵。
僅判斷當前是否有按下的鍵,設置AL後退出。

INT 16H,AH=1 按鍵判斷

ZF=1,無按鍵;

ZF=0,有按鍵,且AX=鍵值代碼。
僅判斷當前是否有按下的鍵,設置ZF後退出。

串操作類指令

重點:MOVS STOS LODS CMPS SCAS REP

串尋址方式

  • 源操作數:SI尋址,默認DS段,允許段超越

  • 目的操作數:DI尋址,默認ES段,不允許段超越

SI DI自動修改(增減1或2)

CLDDF=0,地址指針增1或2

STDDF=1,地址指針減1或2

串傳送 MOVSB MOVSW

ES:[DI]DS:[SI]

SI DI加減1或2

串存儲 STOSB STOSW

ES:[DI]AL/AX

DI加減1或2

串讀取 LODSB LODSW

AL/AXDS:[SI]

SI加減1或2

串比較 CMPSB CMPSW

DS:[SI]-ES:[DI]

SI DI加減1或2

串掃描 SCASB SCASW

AL/AX-ES:[DI]

DI加減1或2

重複前綴指令 REP REPZ REPNZ

配合不影響標誌的MOVS STOS LODSREP前綴

rep movsb相當於:


again:  movsb
        dec cx
        jnz again

rep stosw相當於:


again:  stosw
        dec cx
        jnz again

配合影響標誌的CMPS SCASREPZ REPNZ前綴

REPZ/REPE相當於:CX≠0且ZF=1則繼續比較。

REPNZ/REPNE相當於:CX≠0且ZF=0則繼續比較。

處理機控制類指令

空操作指令 NOP

不執行任何操作,佔用一個字節存儲單元,空耗一個指令執行週期。
常用於程序調試。

段超越前綴指令 CS: SS: DS: ES:

封鎖前綴指令 LOCK

暫停指令 HLT

交權指令 ESC


esc     i6, reg/mem

8086浮點指令交給8087執行。

等待指令 WAIT

實現8086與8087同步運行。