第三章 匯編語言

指令是使計(jì)算機(jī)執(zhí)行某種特定操作的二進(jìn)制編碼。
8086 CPU指令系統(tǒng)有133條指令,通常分為數(shù)據(jù)尋址方式和程序?qū)ぶ贩绞?/strong>
8086指令是不定長,一般為1~6個字節(jié)。

數(shù)據(jù)尋址方式

  1. 隱含尋址
    指令已經(jīng)默認(rèn)對CPU中的某個寄存器進(jìn)行操作,不用在指令中指明所使用的寄存器,即隱含了規(guī)定的操作數(shù),這樣的尋址方式稱為隱含尋址。

  2. 立即數(shù)尋址

  3. 寄存器尋址

  4. 存儲器操作數(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

  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)直接尋址

  1. 短跳轉(zhuǎn):把IP的內(nèi)容加上一個字節(jié)的補(bǔ)碼數(shù)作為新的IP,往前最多跳-128個字節(jié),往后最多跳127個字節(jié)。

  2. 近跳轉(zhuǎn):把IP的內(nèi)容加上兩個字節(jié)的補(bǔ)碼數(shù)作為新的IP,往前最多跳-32768個字節(jié),往后最多跳32767個字節(jié)。

段內(nèi)間接尋址

將寄存器或存儲器操作數(shù)的內(nèi)容賦給IP

段間直接尋址

直接在指令中給出新的CS和IP內(nèi)容

段間間接尋址

用存儲器操作數(shù)的內(nèi)容賦給CS和IP

8086指令格式

指令一般由1~6個字節(jié)組成,具體格式如下圖:


image.png
  1. 字節(jié)1
  • OPCODE:指令操作碼

  • D:操作數(shù)傳輸方向(立即數(shù)指令和串操作指令除外)

    • D=0,Reg為源操作數(shù)
    • D=1,Reg為目的操作數(shù)
  • W:操作數(shù)字節(jié)長度

    • W=0,字節(jié)操作
    • W=1,字操作
  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
  1. 字節(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ù)傳送指令

  1. 通用數(shù)據(jù)傳送指令 MOV DST,SRC

  2. 堆棧及堆棧操作
    堆棧是一種按先進(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ù)指令

  1. 加法指令
  • ADD DST,SRC : (DST) ← (SRC) + (DST)
  • ADC DST,SRC : (DST) ← (SRC) + (DST)+CF
  • INC DST : (DST) ←(DST)+1 //不影響進(jìn)位標(biāo)志CF
  1. 減法指令
  • 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)志 //比較指令
  1. 乘法指令
  • 無符號數(shù)乘法
    MUL SRC : (AX) ←(AL)*(SRC)或(DX,AX) ←(AX)*(SRC)

  • 有符號數(shù)乘法
    IMUL SRC : (AX) ←(AL)(SRC)或(DX,AX) ←(AX)(SRC)

  1. 除法指令 //除數(shù)必須為被除數(shù)一半字長
  • 無符號數(shù)除法指令 DIV SRC
    (AL) ←(AX)/(SRC);(AH) ←(AX)%(SRC)
    或(AX)←(DX,AX)/(SRC);(DX) ←(DX,AX)%(SRC)

  • 有符號數(shù)除法指令 IDIV SRC : 操作與DIV相同

  1. 類型轉(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

  1. 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)整

邏輯指令

  1. 邏輯運(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)志
  1. 移位指令
  • 邏輯左移指令 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

串處理指令

  1. 數(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決定
  1. 字符串掃描和比較指令
  • 串比較指令 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)移指令

  1. 無條件轉(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)
  1. 條件轉(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)移
  1. 循環(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)移
  1. 子程序調(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)用與返回

  1. 中斷調(diào)用
  • INT n
    依次將FLAG,當(dāng)前CS和IP(即斷點(diǎn)地址)放入堆棧,清除IF和TF。執(zhí)行中斷類型碼為n的中斷服務(wù)程序。
    注: INT n 的機(jī)器碼為 CDH n,INT 3 的機(jī)器碼特殊,為 CCH

  • INTO
    在有符號數(shù)運(yùn)算結(jié)束以后,可以使用INTO,若OF=1,則執(zhí)行中斷指令I(lǐng)NT 4,否則無操作。

  • IRET
    中斷返回指令,從中斷程序返回主程序,恢復(fù)斷點(diǎn)和FLAG

控制類指令

  1. 標(biāo)志處理指令
  • CLC/STC/CMC 對CF 清0 / 置位 /取反
  • CLD/STD 對DF 清0 / 置位
  • CLI/STI 對IF 清0 / 置位
  1. 處理器控制指令
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í)行完為止
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容