指令是使計(jì)算機(jī)執(zhí)行某種特定操作的二進(jìn)制編碼。
8086 CPU指令系統(tǒng)有133條指令,通常分為數(shù)據(jù)尋址方式和程序?qū)ぶ贩绞?/strong>
8086指令是不定長,一般為1~6個字節(jié)。
數(shù)據(jù)尋址方式
隱含尋址
指令已經(jīng)默認(rèn)對CPU中的某個寄存器進(jìn)行操作,不用在指令中指明所使用的寄存器,即隱含了規(guī)定的操作數(shù),這樣的尋址方式稱為隱含尋址。立即數(shù)尋址
寄存器尋址
存儲器操作數(shù)尋址
執(zhí)行單元EU根據(jù)指令中給出的尋址方式計(jì)算出16位的偏移量,稱為有效地址(EA)送到總線接口單元BIU,經(jīng)過加法器生成20位實(shí)際物理地址,在存儲器讀寫總線周期對存儲器進(jìn)行操作,一般在表示EA時,用 [操作數(shù)] 表示。
由于計(jì)算EA需要時間,進(jìn)行總線操作比較慢,因此存儲器操作尋址比前三種要慢。
直接尋址
例:MOV SI, [2000H]
默認(rèn)使用DS段,若需使用其他段可使用段超越:MOV SI, ES:[2000H]-
寄存器間接尋址
可間接尋址的寄存器有:BX、BP、SI、DI
例:MOV AL, [BX]BX用于間接尋址時,默認(rèn)段寄存器為DS,允許段超越 BP用于間接尋址時,默認(rèn)段寄存器為SS,允許段超越 SI用于間接尋址時,默認(rèn)段寄存器為DS,允許段超越 DI用于間接尋址時,只有在串操作指令中,默認(rèn)段寄存器為ES,其余情況默認(rèn)段寄存器均為DS,不允許段超越
注:IP只能在代碼段中(CS)尋址,SP只能在堆棧段(SS)中尋址
-
寄存器相對尋址
基址尋址
操作數(shù)的有效地址是一個基址寄存器的內(nèi)容加上一個8位或者16位的偏移量,基址寄存器是BX或者BP。
例:MOV AX,[BX+1000H]
有時也寫成 MOV AX,1000H[BX]或MOV AX,[BX]1000H變址尋址
操作數(shù)的有效地址是一個變址寄存器的內(nèi)容加上一個8位或者16位的偏移量,變址寄存器是SI和DI。
例:MOV AX, ARRAY[SI]基址加變址尋址
操作數(shù)的有效地址是由基址寄存器和變址寄存器的內(nèi)容相加產(chǎn)生
例:MOV AX, [BP+SI]相對的基址加變址尋址
操作數(shù)的有效地址是由基址寄存器、變址寄存器和偏移量三者相加產(chǎn)生。
例:MOV AX, [BX+SI+3H]
也可寫成MOV AX,3H[BX][SI]或MOV AX,3H[BX+SI]數(shù)據(jù)串尋址
DS:SI指示源串,ES:DI指示目的串,串長度計(jì)數(shù)用CX,并自動修改指針和計(jì)數(shù)器值,只用于串操作命令。
例:MOVSB ;((ES:DI))((DS:SI)),CX=CX-1,SI=SI+1,DI=DI+1
- I/O端口尋址
操作數(shù)存放在I/O端口中,指令執(zhí)行時必須通過累加器(AX或AL)實(shí)現(xiàn)對端口的訪問
直接端口尋址
指令直接提供8位端口的地址。
例:IN AL, 63H
當(dāng)端口地址用一個字節(jié)來表示時,可使用直接端口尋址間接端口尋址
由DX寄存器給出16位端口地址。
例:MOV DX, 162H
IN AX, DX
程序?qū)ぶ贩绞?/h1>
段內(nèi)直接尋址
短跳轉(zhuǎn):把IP的內(nèi)容加上一個字節(jié)的補(bǔ)碼數(shù)作為新的IP,往前最多跳-128個字節(jié),往后最多跳127個字節(jié)。
近跳轉(zhuǎn):把IP的內(nèi)容加上兩個字節(jié)的補(bǔ)碼數(shù)作為新的IP,往前最多跳-32768個字節(jié),往后最多跳32767個字節(jié)。
段內(nèi)間接尋址
短跳轉(zhuǎn):把IP的內(nèi)容加上一個字節(jié)的補(bǔ)碼數(shù)作為新的IP,往前最多跳-128個字節(jié),往后最多跳127個字節(jié)。
近跳轉(zhuǎn):把IP的內(nèi)容加上兩個字節(jié)的補(bǔ)碼數(shù)作為新的IP,往前最多跳-32768個字節(jié),往后最多跳32767個字節(jié)。
將寄存器或存儲器操作數(shù)的內(nèi)容賦給IP
段間直接尋址
直接在指令中給出新的CS和IP內(nèi)容
段間間接尋址
用存儲器操作數(shù)的內(nèi)容賦給CS和IP
8086指令格式
指令一般由1~6個字節(jié)組成,具體格式如下圖:

- 字節(jié)1
OPCODE:指令操作碼
-
D:操作數(shù)傳輸方向(立即數(shù)指令和串操作指令除外)
- D=0,Reg為源操作數(shù)
- D=1,Reg為目的操作數(shù)
-
W:操作數(shù)字節(jié)長度
- W=0,字節(jié)操作
- W=1,字操作
- 字節(jié)2,尋址方式
- MOD:尋址方式字段
- 00=存儲器方式,指令中無偏移量
- 01=存儲器方式,指令中有8位偏移量
- 10=存儲器方式,指令中有16位偏移量
- 11=寄存器方式,指令中無偏移量
- Reg:寄存器編碼字段
| 000=AL/AX | 100=AH/SP | 001=CL/CX | 101=CH/BP |
|---|---|---|---|
| 010=DL/DX | 110=DH/SI | 011=BL/BX | 111=BH/DI |
- R/M:寄存器/存儲器字段
- 在MOD=11,寄存器模式下,R/M給出第二個操作數(shù)的寄存器編碼。
-
在MOD≠11,存儲器模式下,R/M給出計(jì)算有效地址的方法。
image.png
- 字節(jié)3~字節(jié)6
DISP:存儲器操作數(shù)地址偏移量,長度由MOD字段定義
DATA:指令中的立即數(shù)
8086指令系統(tǒng)
操作數(shù)符號表示
| 符號 | 含義 |
|---|---|
| DST | 目的操作數(shù) |
| SRC | 源操作數(shù) |
| TARGET | 循環(huán)、轉(zhuǎn)移和調(diào)用指令操作數(shù) |
| imm | 立即操作數(shù),字節(jié)或字 |
| acc | 累加器AL或AX |
| reg | 寄存器操作數(shù) |
| seg_reg | 段寄存器 |
| mem | 存儲器操作數(shù) |
| short_label | 短標(biāo)號(8位偏移量) |
| near_label | 近標(biāo)號(16位地址或偏移) |
| far_label | 遠(yuǎn)標(biāo)號(32位地址) |
數(shù)據(jù)傳送指令
通用數(shù)據(jù)傳送指令 MOV DST,SRC
堆棧及堆棧操作
堆棧是一種按先進(jìn)后出(FILO)原則存取的存儲器,它由堆棧指針寄存器SS:SP和RAM中的一部分組成,主要用于子程序調(diào)用或中斷子程序的現(xiàn)場保護(hù)和恢復(fù),以及參數(shù)傳遞等。
SP的內(nèi)容總是指向棧頂,即最后推入信息所在單元。
進(jìn)棧指令 PUSH SRC
出棧指令 POP DST
交換指令 XCHG DST,SRC
-
累加器專用傳送指令
- 輸入指令 IN AL/AX,PORT/DX
- 輸出指令 OUT PORT/DX,AL/AX
PORT為8位直接地址 - 換碼指令 XLAT : (AL)←((BX)+(AL))
-
地址傳送指令
- 有效地址傳送指令 LEA reg16,SRC:(reg16) ←SRC
- 指針?biāo)图拇嫫骱虳S
LDS reg16,mem32 :(reg16) ←(mem32);(DS) ←(mem32+2) - 指針?biāo)图拇嫫骱虴S
LES reg16,mem32 :(reg16) ←(mem32); (ES) ←(mem32+2)
-
標(biāo)志寄存器傳送
- LAHF : (AH) ←(flag低字節(jié))
- SAHF : (flag低字節(jié)) ←(AH)
- PUSHF : (SP) ←(SP)-2, ((SP)+1),(SP)) ←flag
- POPF : flag ←((SP)+1),(SP)), (SP) ←(SP)+2
算術(shù)指令
- 加法指令
- ADD DST,SRC : (DST) ← (SRC) + (DST)
- ADC DST,SRC : (DST) ← (SRC) + (DST)+CF
- INC DST : (DST) ←(DST)+1 //不影響進(jìn)位標(biāo)志CF
- 減法指令
- SUB DST,SRC : (DST) ←(DST)-(SRC)
- SBB DST,SRC : (DST) ←(DST)-(SRC)-CF
- DEC DST : (DST) ←(DST)-1 //不影響進(jìn)位標(biāo)志CF
- NEG DST : (DST)=0-(DST) //求補(bǔ)指令
- CMP DST,SRC : (DST)-(SRC),僅影響標(biāo)志 //比較指令
- 乘法指令
無符號數(shù)乘法
MUL SRC : (AX) ←(AL)*(SRC)或(DX,AX) ←(AX)*(SRC)有符號數(shù)乘法
IMUL SRC : (AX) ←(AL)(SRC)或(DX,AX) ←(AX)(SRC)
- 除法指令 //除數(shù)必須為被除數(shù)一半字長
無符號數(shù)除法指令 DIV SRC
(AL) ←(AX)/(SRC);(AH) ←(AX)%(SRC)
或(AX)←(DX,AX)/(SRC);(DX) ←(DX,AX)%(SRC)有符號數(shù)除法指令 IDIV SRC : 操作與DIV相同
- 類型轉(zhuǎn)換指令
字節(jié)轉(zhuǎn)換成字指令(有符號數(shù))CBW
若(AL) <80H則(AH)←0,否則(AH) ←FFH即將AL符號位擴(kuò)展到AH有符號字轉(zhuǎn)換成雙字指令CWD
若(AX)<8000H,則(DX) ←0,否則(DX) ←FFFFH
- BCD碼調(diào)整指令
加減運(yùn)算非壓縮BCD碼高4位的值可不為0,乘除時高4位必須是0。
-
壓縮BCD碼調(diào)整指令
- DAA :對BCD碼加法運(yùn)算結(jié)果(AL)進(jìn)行調(diào)整。
- DAS :對BCD碼減法運(yùn)算結(jié)果(AL)進(jìn)行調(diào)整。
-
非壓縮BCD碼調(diào)整
- AAA :對非壓縮BCD碼加法運(yùn)算結(jié)果進(jìn)行調(diào)整,進(jìn)位送(AH)中
- AAS :對非壓縮BCD碼減法運(yùn)算結(jié)果進(jìn)行調(diào)整
- AAM :對非壓縮BCD碼乘法運(yùn)算進(jìn)行調(diào)整
- AAD :對非壓縮BCD碼除法運(yùn)算進(jìn)行調(diào)整
邏輯指令
- 邏輯運(yùn)算指令
- AND DST,SRC (DST) ←(DST)&(SRC)
- OR DST,SRC (DST) ←(DST)|(SRC)
- NOT DST ~DST
- XOR DST,SRC (DST) ←(DST)^(SRC)//異或
- TEST DST,SRC (DST)&(SRC),僅影響標(biāo)志
- 移位指令
- 邏輯左移指令 SHL DST,count :DST左移count位,每左移一位,最低位補(bǔ)0,最高位進(jìn)入CF
- count可以為數(shù)字,也可以為CL做移位計(jì)數(shù)。
- 算術(shù)左移指令 SAL DST,count :同SHL
- 邏輯右移指令 SHR DST,count :最高位添零,最低位進(jìn)入CF
- 算術(shù)右移指令 SAR DST,count :最高位不變,最低位進(jìn)入CF
- 循環(huán)左移指令 ROL DST,count :最高位進(jìn)入CF和最低位
- 循環(huán)右移指令 ROR DST,count :最低位進(jìn)入CF和最高位
- 帶進(jìn)位循環(huán)左移指令 RCL DST,count
- 帶進(jìn)位循環(huán)右移指令 RCR DST,count
串處理指令
- 數(shù)據(jù)串傳送指令:唯一的目的操作數(shù)和源操作數(shù)都在存儲器中的指令
-
串傳送指令 MOVSB/MOVSW :DST與SRC做類型檢查
- MOVSB : ((ES:DI)) ←((DS:SI)),(SI) ←(SI)±1, (DI)←(DI)±1
- MOVSW :((ES:DI)) ←((DS:SI)),(SI) ←(SI)±2, (DI) ←(DI)±2
其中,加、減地址指針SI和DI由FLAG中的DF決定,DF=0地址增加,DF=1地址減小。
-
建立方向標(biāo)志指令
- CLD ;DF←0
- STD ;DF←1
REP重復(fù)前綴
例:REP MOVSB :以CX寄存器做計(jì)數(shù)器,每傳送一個數(shù)(CX)減1,直到(CX)為0。
REPZ/REPE : 若(CX)≠0且ZF=1時繼續(xù)執(zhí)行,否則退出。
REPNZ/REPNE : 若(CX)≠0且ZF=0(比較不相等)時繼續(xù)執(zhí)行,否則退出。-
存入串指令 STOSB/STOSW : DST做類型檢查
- STOSB : ((ES:DI)) ←(AL), (DI) ←(DI)±1
- STOSW : ((ES:DI)) ←(AX),(DI) ←(DI)±2
由DF決定方向,可加入前綴REP。
-
從串中取指令 LODSB/LODSW :SRC做類型檢查
- LODSB : (AL) ←((DS:SI)) , (SI) ←(SI)±1
- LODSW : (AX) ←((DS:SI)) ,(SI) ←(SI)±2
地址增減由DF決定
- 字符串掃描和比較指令
-
串比較指令 CMPS : SRC和DST僅做類型檢查
- CMPSB ;((DS:SI))-((ES:DI)), (SI) ←(SI)±1, (DI) ←(DI)±1
- CMPSW ;((DS:SI))-((ES:DI)), (SI) ←(SI)±2, (DI) ←(DI)±2
串比較僅影響標(biāo)志,地址增減由DF決定。
-
串掃描指令 SCAS : DST做類型檢查
- SCASB : (AL)-((ES:DI)) ,(DI) ←(DI)±1
- SCASW : (AX)-((ES:DI)) ,(DI) ←(DI)±2
僅影響標(biāo)志,地址增減由DF決定,可加條件前綴。
控制轉(zhuǎn)移指令
- 無條件轉(zhuǎn)移指令:JMP TARGET
- JMP short_label :(IP)<-(IP)+short_label 短跳轉(zhuǎn)
- JMP near_label :(IP)<-(IP)+near_label 近跳轉(zhuǎn)
- JMP far_label :(CS:IP)<-far_label 遠(yuǎn)跳轉(zhuǎn)
- 條件轉(zhuǎn)移指令
- 根據(jù)單個標(biāo)志轉(zhuǎn)移
| 指令 | 含義 | 測試條件 |
|---|---|---|
| JZ short_label | 結(jié)果為0轉(zhuǎn)移 | ZF=1 |
| JE short_label | 結(jié)果相等轉(zhuǎn)移 | ZF=1 |
| JNZ short_label | 結(jié)果不為0則轉(zhuǎn)移 | ZF=0 |
| JNE short_label | 結(jié)果不相等則轉(zhuǎn)移 | ZF=0 |
| JS short_label | 結(jié)果為負(fù)則轉(zhuǎn)移 | SF=1 |
| JNS short_label | 結(jié)果非負(fù)則轉(zhuǎn)移 | SF=0 |
| JNO short_label | 結(jié)果不溢出則轉(zhuǎn)移 | OF=0 |
| JO short_label | 結(jié)果溢出則轉(zhuǎn)移 | OF=1 |
| JP short_label | 奇偶為1則轉(zhuǎn)移 | PF=1 |
| JPE short_label | 偶轉(zhuǎn)移 | PF=1 |
| JNP short_label | 奇偶為0則轉(zhuǎn)移 | PF=0 |
| JPO short_label | 奇轉(zhuǎn)移 | PF=0 |
| JB short_label | 有借位轉(zhuǎn)移 | CF=1 |
| JNAE short_label | 不大于等于轉(zhuǎn)移 | CF=1 |
| JC short_label | 有進(jìn)位轉(zhuǎn)移 | CF=1 |
| JNB short_label | 無借位轉(zhuǎn)移 | CF=0 |
| JAE short_label | 大于等于轉(zhuǎn)移 | CF=0 |
| JNC short_label | 無進(jìn)位轉(zhuǎn)移 | CF=0 |
- 兩個無符號數(shù)比較轉(zhuǎn)移
| A大于 | B小于 | E等于 |
|---|---|---|
| JB/JNAE/JC | CF=1 | 小于 |
| JNB/JAE/JNC | CF=0 | 不小于 |
| JBE/JNA | CF|ZF=1 | 不大于 |
| JNBE/JA | CF|ZF=0 | 大于 |
- 兩個有符號數(shù)比較轉(zhuǎn)移
| G大于 | L小于 | E等于 |
|---|---|---|
| JL/JNGE | SF^OF=1 | 小于 |
| JNL/JGE | SF^OF=0 | 不小于 |
| JNLE/JG | (SF^OF)|ZF=0 | 大于 |
| JLE /JNG | (SF^OF)|ZF=1 | 不大于 |
- 測試CX值,為0則轉(zhuǎn)移
JCXZ short_label :(CX)=0則轉(zhuǎn)移
- 循環(huán)指令
- LOOP short_label : (CX) ←(CX)-1,(CX)≠0則轉(zhuǎn)移
- LOOPZ/LOOPE short_label : (CX) ←(CX)-1,(CX)≠0且ZF=1則轉(zhuǎn)移
LOOPNZ/LOOPNE short_label :(CX) ←(CX)-1,(CX)≠0且ZF=0則轉(zhuǎn)移
- 子程序調(diào)用與返回
子程序調(diào)用指令 CALL TARGET
具體指令
CALL near_proc;段內(nèi)調(diào)用
CALL far_proc;段間調(diào)用
CALL mem16/regp16/mem32;返回指令 RET
帶立即數(shù)返回 RET IMM16
在RET指令的基礎(chǔ)上,當(dāng)從堆棧中彈出IP和CS后,再將SP加上一個字的立即數(shù),使得返回后(SP) ← (SP) + IMM16
中斷調(diào)用與返回
- 中斷調(diào)用
INT n
依次將FLAG,當(dāng)前CS和IP(即斷點(diǎn)地址)放入堆棧,清除IF和TF。執(zhí)行中斷類型碼為n的中斷服務(wù)程序。
注: INT n 的機(jī)器碼為 CDH n,INT 3 的機(jī)器碼特殊,為 CCHINTO
在有符號數(shù)運(yùn)算結(jié)束以后,可以使用INTO,若OF=1,則執(zhí)行中斷指令I(lǐng)NT 4,否則無操作。IRET
中斷返回指令,從中斷程序返回主程序,恢復(fù)斷點(diǎn)和FLAG
控制類指令
- 標(biāo)志處理指令
- CLC/STC/CMC 對CF 清0 / 置位 /取反
- CLD/STD 對DF 清0 / 置位
- CLI/STI 對IF 清0 / 置位
- 處理器控制指令
| NOP | 空操作指令 | 占用一個字節(jié)的機(jī)器碼,不執(zhí)行任何操作 |
|---|---|---|
| HLT | (Halt)停機(jī)指令 | 該指令使處理器處于停機(jī)狀態(tài),以便等待一次外部中斷到來 |
| WAIT | 等待指令 | 該指令使處理器處于空轉(zhuǎn)狀態(tài),也可用來等待外部中斷的到來 |
| ESC | (Escape)換碼指令,用作前綴 | 格式:ESC MEM,其中MEM指出一個存儲單元,ESC指令把該存儲單元的內(nèi)容送到數(shù)據(jù)總線去 |
| LOCK | 封鎖指令,用作前綴 | 該指令與其他指令聯(lián)合,用來維持總線的封鎖信號直到與其聯(lián)合的指令執(zhí)行完為止 |
