1. 程式人生 > 其它 >組合語言學習筆記(4)——彙編基本指令集

組合語言學習筆記(4)——彙編基本指令集



注:為講授方便,使用下列符號:

N 代表立即數 N8、N16、N32代表8、16、 32位立即數
R 代表暫存器運算元 R8、R16、R32代 表8、16、32位暫存器運算元
M 代表記憶體運算元 M8、M16、M32代 表8、16、32位記憶體運算元
S 代表段暫存器


一、傳送類指令

 1. 通用傳送

  • 資料傳送
    • 功能:源→目,源不變,不影響6種標誌
    • 說明:CS不能做目標,不能向段暫存器寫入立即數 ;禁止2個記憶體單元直接傳送 ;源、目屬性要一致
  • 有效地址傳送
    • 功能:計算記憶體單元的有效地址(不是其中的運算元)→目標
      • LEA BX , BUF;將BUF單元的有效地址→BX
      • LEA BX , [SI+5] ;將資料段SI+5變址的那個單元的有效地址→BX
    • 注:有效地址就是偏移地址,LEA指令等效於 OFFSET運算子;LEA BX,BUF 等效於 MOV BX,OFFSET BUF
  • 交換指令
    • 功能:完成2個運算元互換
    • 說明: 段暫存器、立即數不能參加互換 !;2個記憶體運算元不能互換,源、目的型別一致

 2 . 堆疊操作指令

  • 棧頂:棧區的低地址
  • 棧底:棧區的高地址
  • 堆疊段暫存器SS:存放堆 棧段段基址
  • 堆疊指標ESP(SP):存放 棧頂單元的偏移地址
  • SS、ESP(SP)初值,由程式 員賦值或DOS系統自動賦值
  • 堆疊指標SP的初值決定了堆疊的大小,SP 始終指向堆疊的頂部,即始終指向最後壓入堆疊的資訊所在的單元 。
  • 堆疊指令
    • 堆疊指令
      • 說明:非直接定址的記憶體運算元,必須用PTR說明屬性
    • 出棧指令
      • 說明: 非直接定址的記憶體運算元,必須用PTR說明屬性
    • 16位暫存器進棧/出棧
      • PUSHA ;依次把AX、CX、DX、BX、 SP、BP、SI、DI壓棧(共2´8 位元組)
      • POPA ;從棧頂彈出2*8位元組依次放入DI、 SI、BP、SP、BX、DX、CX、 AX

        



二、算數運算

  • 加減法
    • 功能:ADD :源+目→目
    • SUB :目–源→目
    • ADC :源+目+上條指令執行後的C標→目
    • SBB :目–源–上條指令執行後的C標→目
    • 注:此四種操作都影響A、C、O、P、S、Z標誌
    • 說明:源、目運算元的屬性(長度)要一致 ;若運算元中有記憶體運算元時,請注意是 否需要使用PTR運算子。
  • 二進位制加減法
    • 功能:I NC:目+1→目;影響A、O、P、S、Z,不影響C標
      • I NC:目+1→目;影響A、O、P、S、Z,不影響C標
      • I NC:目+1→目;影響A、C、O、P、S、Z
    • 說明:對於非直接定址的記憶體運算元,要用PTR 明確說明屬性
  • 比較指令
    • 功能:目-源,產生A、C、O、P、S、Z 6個狀態標誌, 不破壞源、目。該指令一般後跟條件轉移指令。
    • 說明:★ 源、目運算元不能同為M ★ 運算元中出現記憶體運算元時,請注意是否需 要使用PTR運算子
  • 二進位制乘法
    • ★ MUL預設乘數、被乘數、乘積為無符號二進數
    • ★ IMUL預設乘數、被乘數、乘積為有符號二進數
    • ★ 高位積為0,則C標、O標=0,否則為1
    • ★ 乘數、被乘數等長,乘積為雙倍長
    • 說明:源、目不能同為M
    • 功能:源×目→目
    • 功能:源×立即數→目
  • 二進位制除法
    • 功能:
    • 說明:★ DIV預設除數、被除數、商、餘數均為無 符號數;IDIV預設除數、被除數、商、餘數 均為有符號數
    • ★ 被除數應為除數的雙倍長
    • ★ 如除數太小,使商超出範圍,則引發CPU中斷 ,具體處理方法由作業系統決定,若為DOS操作 系統,則顯示:Divided overflow 後返回DOS
  • BCD碼調整指令
    • 組合/未組合BCD碼數(即壓縮/未壓縮BCD 碼數)
      • 組合BCD碼:一位元組中含有2位BCD碼
      • 未組合BCD碼:一位元組中含有1位BCD碼(高4位為0)
      • 注意:1010~1111不是BCD碼
    • BCD碼數的加減運算
      • 指令系統中沒有實現BCD碼數加法的指令,只能借用ADD、ADC指令。但是ADD、ADC指令默 認運算元是二進數,其運演算法則是“逢二進一” , 而BCD碼數加法要求按“逢十進一”運算。
      • 因此借用ADD、ADC指令進行BCD碼數的加 法還必須對結果進行修正,修正後的結果才是 BCD碼數的和數。
      • 事實上,N1和N2可以是任意的BCD碼數, 借用ADD、ADC運算後必須具體分析運算結果, 然後根據不同的情況選擇加06H修正,或是加 60H修正,或是加66H修正。 因此借用ADD、ADC指令進行BCD碼數的加 法還必須對結果進行修正,修正後的結果才是 BCD碼數的和數。
      • 如果對於每一次BCD碼數的加法都要由 程式設計師來判斷結果的話,這太麻煩了,因此 指令系統中設計了一條“組合BCD碼數加法 調整指令¾¾DAA”由硬體進行分析,再對 結果進行調整。
      • 上例程式設計時只需要按以下方式設計程式即可

  

    • 組合BCD碼加法調整:DAA
      • 功能:預設操作物件為AL,並且根據具體情況對 AL中的高/低4位進行修正。
      • 應用:緊跟在以AL為目標暫存器的ADD/ADC之 後,但AL中必須是組合BCD碼數之和。


三、轉移和呼叫指令

  • 轉移類指令分類
    • 按照轉移條件分:無條件轉移和有條件轉移
    • 按照轉移範圍分:段內轉移和段間轉移
    • 按照獲取轉移地址的方法分: 直接轉移和間接轉移
  • 無條件轉移
    • 功能:無條件轉移,執行指定標號處的指令
    • 說明: ①標號是轉移地址標號。 ②SHORT是短轉移,其轉移範圍相對於指令地址 而言在+129~ -126個單元之間。③段內“JMP 標號”,在真實模式下,可轉移到64K程式碼 段的任何位置。
  • 有條件轉移
    • 按標誌位的當前狀態轉移(設轉移地址標號為XYZ)

JC  XYZ       ;當前C標誌為1轉
JNC XYZ       ;當前C標誌為0轉
JZ  XYZ       ;當前Z標誌為1轉
JNZ XYZ       ;當前Z標誌為0轉
JC  XYZ       ;當前C標誌為1轉
JNC XYZ       ;當前C標誌為0轉
JZ  XYZ       ;當前Z標誌為1轉
JNZ XYZ       ;當前Z標誌為0轉
    • 無符號數條件轉移(設轉移地址標號為XYZ)
      • 應用:CMP N1, N2 ;N1,N2為無符號數
JA  XYZ     ;N1 > N2轉
JNA XYZ     ;N1≤N2轉
JC  XYZ     ;N1 < N2轉
JNC XYZ     ;N1 ≥ N2轉
    • 有符號數條件轉移(設轉移地址標號為XYZ)
      • 應用:CMP N1,N2; N1,N2 為有符號數(機器數)
JG  XYZ     ;被減數的真值大於減數的真值轉
JGE XYZ     ;被減數的真值大於等於減數的真值轉
JL  XYZ     ;被減數的真值小於減數的真值轉
JLE XYZ     ;被減數的真值小於等於減數的真值轉
    • 迴圈控制轉移
LOOP XYZ     ;CX-1→ CX, 結果不為零轉
      • 注意:迴圈控制轉移,其轉移範圍相對於指令地址 而言為:-126 ~+129
  • 呼叫與返回指令
    • ★ 呼叫:呼叫子程式,即無條件轉到子程式的第一條指令
    • ★ 返回:返回斷點,即返回到CALL的後繼指令
    • ★ 子程式:能完成一定功能的相對獨立的程式段
    • 組合語言的子程式(也稱為過程)定義語句
過程名   PROC   屬性
      子程式實體
      RET
過程名    ENDP
    • 說明:
      • 過程名,即子程式名,以字母開頭,長度≤31 ! 經彙編之後,過程名就是子程式第一條指令的地址。
      • PROC/ENDP 是子程式的定界語句
      • 屬性 有2種描述:1、NEAR(或預設)代表近過程,即該子程式和呼叫它的那條指令在同一個程式碼段;2、FAR 代表遠過程,即該子程式和呼叫它的那條指令不在同一個程式碼段
      • RET子程式返回指令
    • 段內呼叫
      • 功能:斷口偏移地址→堆疊
        • (SP)←(SP)-2 [CS:IP]←(IP)
      • 子程式入口的偏移地址→IP,從而轉子程式
    • 段間呼叫
      • 功能: 斷口的“段基址:偏移地址”→堆疊
        • 首先 (SP)←(SP)-2 [ CS:IP ]←(CS)
        • 然後 (SP)←(SP)-2 [ CS:IP ]←(IP)
      • 子程式入口的“段基址:偏移地址”→CS:IP, 實現段間轉移
    • 段內/段間返回指令 RET
      • 功能: 有NEAR屬性的RET指令,從棧頂彈出2位元組→IP
      • (IP)←[CS:IP] (SP)←(SP) + 2
      • 有FAR屬性的RET指令,從棧頂彈出4位元組→IP,CS
      • (IP)←[CS:IP] (SP)←(SP) + 2
      • (CS)←[CS:IP] (SP)←(SP) + 2
      • 如果棧頂是斷口地址,則能返回斷點,否則不能
  • 中斷呼叫與中斷返回
    • 中斷呼叫  INT N (N=0 ~ 255)
      • 功能:標誌暫存器→ 堆疊
      • “ INT N ”的後繼指令地址“CS:IP”→堆疊 無條件轉向N型中斷服務程式
    • 中斷返回 IRET
      • 功能:從棧頂依次彈出6 個元素→ IP,CS,標誌暫存器


四、邏輯運算

說明:移位指令的運算元為R/M, 移位次數可以是立即數或CL



五、串操作指令

  • 串(記憶體串)的定義: 記憶體中若干連續的變數(位元組,字或雙字)
  • 關於串操作指令的總說明
    • 80X86有6條串操作指令,它們是串傳送、串比較、串搜尋、串裝入、串儲存和I/O串操作,本小節僅介紹前5條。
    • 各種串操作指令雖然功能不同,但有許多共同之處,例如: 源串和目標串的儲存及定址方式都有隱含規定,即:源串要 放在資料段,目標串要放在ES附加段,在16位定址操作,CPU 自動用SI間址訪問資料段,用DI間址訪問ES附加段、用CX做 為串計數器。在32位定址操作下,CPU自動用ESI間址訪問數 據段,用EDI間址訪問ES附加段,用ECX做串計數器。
    • 由於真實模式下邏輯段的最大體積為64K,沒有必要使用32 位定址,為了描述方便,在介紹指令功能的時候,均以16位定址為基礎。
  • 串傳送
    • 功能:把DS:[SI]的若干元素→ ES:[DI]的若干單元
    • 說明: ①關於“元素”的概念 在位元組串傳送指令中,一個元素就是1個位元組 在字串傳送指令中,一個元素為2個位元組 在雙字串傳送指令中,一個元素為4個位元組
      • ②指令執行前的準備工作: 源串的首地址/末地址→DS:SI 目串的首地址/末地址→ES:DI D標誌置0/置1
      • ③該指令傳送一個元素後,CPU自動修改SI,DI 當D標誌為0時,SI,DI增量修改 當D標誌為1時,SI,DI減量修改

    • 準備工作:① 同基本型格式 ② 欲傳送的元素個數→CX
  • 串裝入
    • 準備工作:串首址/末址→DS:SI,0/1 →D標
  • 串儲存

    • 準備工作:目標區首址/末址→ES:DI,0/1 →D標

    • 準備工作:同基本型;欲儲存的元素個數→CX
    • 功能:每儲存一個元素,自動修改DI, 且CX-1→CX, CX=0時止
  • 串比較
    • 比較兩串字元是否相等。兩串字元對應字元相等,則兩串字元相等,有一個字元不等,則兩串字元不等
    • 準備工作:源串首址/末址→DS:SI;目串首址/末址→ES:DI ,0/1 →D標
    • 準備工作:同基本型;串元素的個數→ CX
    • Z標誌在具有REPE/REPNE的串指令中的實際使用: 通過Z的取值(Z=0或Z=1)可以判斷重複進行 的串指令是否正常退出,以便進行下一步處理。
  • 串搜尋
    • 在ES:[DI]的目標區,搜尋是否有規定的“關鍵字”  
    • 準備:目標區首址/未址→ES:DI, 0/1 →D標;關鍵字→AL/AX/EAX。
    • 功能:比較AL/AX/EAX=ES:[DI]? 修改DI
      • 若ES:[改前DI]=關鍵字,則Z置1,否則Z置0
    • 準備工作:同基本型;目標串元素的個數→ CX


六、處理機控制指令

  • C標置0 CLC
  • C標置1 STC
  • C標取反 CMC
  • D標置0 CLD
  • D標置1 STD
  • I標置0 CLI
  • I標置1 STI
  • 空操作 NOP
  • 暫停 HLT