1、指令概述
- 指令:通知 CPU執行某種操作的“命令” , CPU全部指令的集合,稱為指令系統
- 指令的書寫格式
- 目標指令(機器指令)格式為:二進制形式的序列(即:一串0,1代碼)。注意:硬件只能識別,存儲,運行目標指令
- 符號指令:用規定的操作碼和操作數助記符, 按照規定的書寫格式書寫的指令,格式為:字 符串形式的序列
- 指令的組成:大多數指令由操作碼和操作數兩個部分組成
- 操作碼:通知CPU執行什么操作(唯一)
- 操作數:指令的操作對象(一個或多個)
- 目標程序的生成
- CPU只能識別,存儲,運行目標指令,而用機器指令編程非常困難。於是早期的專家們發明了符號指令,再經過軟件把符號指令→機器指令。 圖示如下:
- 指令長度:指令在存儲器中占用的字節數稱為指令長度。 86x86指令長度(機器指令長度)為1~16字節。
- 指令地址:單字節指令占用1個內存單元,多字節指令占用連續的內存單元,存放指令第一字節的內存單元地址,稱為“指令地址” 。
- 指令存放:指令存放在內存中時,先存放操作碼,再存放操 作數。多字節操作數連續存放。順序依據小端法原則,即: 低位字節存放在低地址單元,高位字 節存放在相鄰的高地址單元
- 符號指令的書寫格式
-
- 操作碼:CPU執行的操作
- 操作數:指令執行時的操作對象(一個或多個)
- 標號:以字母開頭,后跟字母,數字,下划線,長度 ≤31字符,標號又稱符號地址,代表該指令的邏輯地 址。可有可無,設置是為了程序的轉向
- 注解:以“ ;”開頭,不執行,打印程序清單時照 原樣打印,“系統保留字”不能做標號。
2、尋址方式
- 尋址方式:操作數是指令的操作對象,尋址方式就是在指令中,使用特定的助憶符(地址表達式), 告知 CPU 如何計算出操作數的地址,從而可以正確去除操作數進行后繼指令操作與地址碼有 密切關系。形成操作數地址碼的過程就是尋址。
- 操作數所在的四種不同的物理位置
- 操作數的分類
- 操作數包含在指令中,這種操作數稱為立即數 。
- 操作數存放在CPU的某個寄存器中,這種操作數稱為寄存器操作數。
- 操作數存放在存儲器中,這種操作數稱為存儲器操作數 (內存操作數) 。
- 操作數存放在I/O端口中,這種操作數稱為 I/O端口操作數。
- 立即尋址:操作數包含在本條指令中,是指令 的一部分,完整地取出該條指令,也就獲得了操作數。
-
- 下例源操作數即為立即尋址
MOV EAX,12345678H MOV BL,10101010B ;AAH → BL MOV CL, – 4 ;FCH →CL MOV DL,’A’ ;41H →DL ADD AL,0C8H MOV SI,3*5 ;15 →SI
-
- 立即數書寫規定:
- 立即數以數字開頭,以A~F開頭的16進制數,必須前綴0。
- 立即數的數制用后綴表示,B表示二進制數,H表示十六 進制數, D或缺省為十進制數,單引號括起來的字符編 譯成相應的ASCII碼 。
- 可以用+ – * / 組成立即數表達式
- 立即數書寫規定:
- 寄存器尋址:操作數在CPU的某個寄存器中, 符號指令中直接寫出寄存器名稱。
-
- 下述6條指令,目標操作數即為寄存器尋址
MOV EAX,12345678H MOV BL,10101010B ;AAH → BL MOV CL, – 4 ;FCH →CL MOV DL,’5’ ;35H →DL ADD AL,0C8H MOV SI,3*5 ;15 →SI
-
- 下述指令,目標操作數和源操作數均為寄存器尋址
MOV AX , DS ;DS內容 → AX
-
- 下述單操作數指令,操作數均為寄存器尋址
INC SI ;SI+1 → SI (Increase 增量) DEC DI ;DI – 1 → DI (Decrease 減量)
- 存儲器操作數尋址方式
- 在讀寫內存操作數之前,CPU必須知道相關存 儲單元的物理地址。
- 由於CPU對存儲器采用分段管理, 因此指令格式 中只能寫出存放操作數的內存單元的“邏輯地 址” 。
- 程序員的責任僅在於正確的書寫邏輯地址表達 式,然后由CPU自動運算以求出物理地址。
- 存儲單元邏輯地址表達式的一般形式
-
- 實模式下,物理地址=段寄存器×24 +偏移地址
- 直接尋址
- 地址表達式的格式1:段寄存器:[偏移地址]
- 如:MOV AL, ES:[2CH]
- 注:這種格式很少使用,通常情況下,程序員 並不知道某單元的偏移地址。
- 地址表達式的格式2: 段寄存器:變量名。用變量名代表存儲單元的有效地址
- 地址表達式的格式1:段寄存器:[偏移地址]
-
-
- 匯編語言允許為某單元起一個“名字” ,這個 名字就稱為該單元的“變量名”,經匯編之后, 變量名有段基址和偏移量兩種屬性。
- 由於變量名是唯一的,程序中不能有重復的變 量名, “段寄存器:”可以省略。
- 寄存器間接尋址(寄存器間接尋址又稱間接尋址,間址):操作數在內存單元,該單元的段基址在段寄存器中 有效地址在間址寄存器中,CPU首先進行地址計算
- 間接尋址的地址表達式:段寄存器:[間址寄存器]
- 某單元的物理地址=段寄存器內容×16+間址寄存器
- 訪問約定的邏輯段,間接尋址的地址表達式 簡化為: [間址寄存器]
- 某單元的物理地址=約定的段寄存器內容×16+ 間址寄存器
- 間址寄存器和約定訪問的邏輯段
- 間接尋址的地址表達式:段寄存器:[間址寄存器]
-
-
-
- 注意:BX間址,約定訪問的是數據段,因此, “DS:”可省;BP間址約定訪問的是堆棧段,因此 “DS:”不可省
- 基址尋址
- 在基址尋址中,有效地址由兩部分組成。 一部分在基址寄存器中,另一部分為常量 。
- 基址尋址的地址表達式:段寄存器:[基址寄存器+位移量]
- 物理地址=段寄存器內容×16+基址寄存器+位移量
- 訪問約定的邏輯段,簡化的地址表達式: [基址寄存器+位移量]
- 物理地址=約定的段寄存器內容×16+基址寄存器 +位移量
- 基址寄存器和約定訪問的邏輯段
-
-
- 變址尋址
- 有比例因子的變址尋址其地址表達式為段寄存器:[比例因子*變址寄存器+位移量]
- 物理地址=段寄存器×16+比例因子×變址寄存器 +位移量
- 沒有比例因子的變址尋址其地址表達式為:段寄存器:[變址寄存器+位移量]
- 訪問約定的邏輯段可簡化為 : [變址寄存器+位移量]
- 物理地址=約定的段寄存器×16+變址寄存器+位移量
- 物理地址=約定的段寄存器×16+變址寄存器+位移量
- 有比例因子的變址尋址其地址表達式為段寄存器:[比例因子*變址寄存器+位移量]
- 變址尋址
-
- 基址加變址尋址
- 存儲單元的有效地址由3部分組成
- 有比例因子的基址加變址的地址表達式為: 段寄存器:[基址寄存器+比例因子*變址寄存器+位移量]
- 訪問約定邏輯段其地址表達式簡化為: [基址寄存器+比例因子*變址寄存器+位移量]
- 無比例因子基址加變址的地址表達式為: 段寄存器:[基址寄存器+變址寄存器+位移量]
- 訪問約定邏輯段:[基址寄存器+變址寄存器+位移量]
- 基址寄存器和變址寄存器都是16位或都是32位, 否則(16位尋址和32位尋址混合使用)是非法 指令
- 默認的段寄存器不一致,這樣的組合雖然是合 法,但容易出錯
- 基址加變址尋址
- 要點總結:
- 指令中的操作數有4種:立即數、寄存器 操作數、內存操作數和I/O端口操作數。
- 訪問立即數使用立即尋址方式。
- 訪問寄存器操作數使用寄存器尋址方式。
- 訪問內存操作數有5種尋址方式: 直接尋址、間址、基址、變址、基址加變址。
- 訪問I/O端口操作數使用I/O端口尋址方式。
- 關於16位尋址和32位尋址
- 16位尋址:采用16位間址、基址、變址、基址加變址
- 32位尋址:采用32位間址、基址、變址、基址加變址
- 在實模式下,一個邏輯段的體積最大為64K, 存儲 單元的有效地址為16位,不可能超過 FFFFH,因此,在實模式下運行的程序通常采 用16位尋址
- 關於段約定和段超越在用間址、基址、變址、基址加變址尋址內存操作數時,其地址表達式都有2種書寫格式——有段前綴和無段前綴
- 如用BP、EBP、ESP參與尋址,CPU自動認為是訪問堆棧段, 因此段超越前綴“SS:” 可省
- 如用BP、EBP、ESP參與尋址非堆棧段,必須明確寫出段超越前綴
- 如用BX、SI、DI、EAX~EDX、ESI、EDI參與尋址, CPU自動認為是訪問數據段,因此“ DS:”可省
- 如用BX、SI、DI、EAX、EDX、ESI、EDI參與尋址非數據段,必須明確寫出段超越前綴
- 使用段約定訪問內存操作數是最常用的編程風格
3、標志寄存器
- 80486標志寄存器為32位,實際使用15位
- 15位標志分為兩類:狀態標志和控制標志
- 狀態標志記錄了當前指令執行后的狀態信息
- 控制標志用來控制微處理器操作
- 狀態標志
- C標志—進位/借位標志
- 字節加/減,最高位(D7)產生進位/借位時: C標志置1,否則置0
- 字加/減,最高位(D15)產生進位/借位時: C標志置1,否則置0
- 雙字加/減,最高位(D31)產生進位/借位時: C標志置1,否則置0
- A標志—輔助進位/輔助借位標志
- 字節、字、雙字加/減,D3位產生進位/借位時: A標志置1,否則置0
- S標志—符號標志
- 字節運算后,結果的最高位D7位為1, S標志置1,否則置0
- 字運算后,結果的最高位D15位為1, S標志置1,否則置0
- 雙字運算后,結果的最高位D31位為1, S標志置1,否則置0
- Z標志—結果標志
- 運算結果為全0時,Z標志置1,否則置0
- P標志—奇偶標志(實際上是偶標志)
- 運算結果中,最低的1個字節中“1”的個數為偶數個(沒有“1”也是偶數),P標 志置1,否則置0
- O標志—溢出標志
- 運算結果產生溢出,則O標志置1,否則置0
- C標志—進位/借位標志
4、語句類型和格式
- 語句類型
- 匯編語言源程序包括的語句類型為:指令性語句和指示性語句
- 指令性語句即為通常所說的符號指令。
- 符號指令:經匯編后,其機器指令通知CPU進行什么操作。
- 指示性語句包括偽指令和宏指令。
- 偽指令:是非機器指令,是在匯編鏈接期間 進行操作的。為匯編程序,鏈接程序提供匯編鏈接信息
- 符號指令和偽指令區別
-
- 指令性語句(符號指令)的格式為:
-
- 指示性語句(偽指令)的格式為:
-
- 說明:標號名、變量名命名規則:以除數字以外的字母或符號 開頭,后跟字母、數字…長度≤31個字符
- 常用的偽指令:
- 數據定義:DB、DW、DD、DF、DQ、DT
- DB:字節字義偽指令
- DW:字定義偽指令
- DD:雙字定義偽指令
- DF:三字定義偽指令
- DQ:四字定義偽指令
- DT:五字定義偽指令
- 符號定義:EQU、=
- 用EQU定義的符號常數,其值在后繼語句中不能 更改;用“=”定義的符號常數,其值在后繼語句中 可以重新定義
- 數據定義:DB、DW、DD、DF、DQ、DT
- 常用運算符:$、SEG、OFFSET、PTR、算術運算、邏輯運算、 關系運算
- $運算符
- 匯編程序對源程序是逐行匯編的,$運算符可以返回匯編計數器的當前值。
- 應用:$運算符緊跟在 DB、DW、DD偽指令之后,統 計字符串的長度。
- SEG運算符
- 格式: SEG 段名或變量名或標號名
- 功能: 計算某一邏輯段的段基址
- OFFSET運算符
- 格式:OFFSET 變量名或標號名
- 功能:算出某個變量或標號名所在單元的 相對於段首的偏移地址(有效地址)。
- PTR運算符
- 格式: 類型說明符 PTR 地址表達式
- 功能: 在本條指令中臨時修改地址表達式的屬性
- 應用:在下列指令中必須用PTR臨時修改或者顯示說明 內存操作數的屬性
- 在雙操作數指令中(如:MOV,ADD,SUB,CMP……)
- 源操作數為立即數,目標為直接尋址的內存操作數, 當二者類型屬性不一致時,后者必須用PTR臨時修改其 屬性,使源目兩個操作數類型屬性一致。
- 源為單字節/雙字節立即數,目標操作數為間址、 變址、基址或基址加變址尋址的內存操作數,無論兩者 類型屬性是否已經一致,后者都必須用PTR顯示說明其 屬性,使其與源操作數屬性一致。
- 源操作數,目標操作數中有一方為直接尋址的內存 器操作數,但二者類型屬性不一致,必須用PTR臨時修 改其中存儲器操作數的屬性 。
- 在單操作數指令中(如:INC,DEC……)
- 操作數為間址、變址、基址或基址加變址尋址的存儲器操作數,必須用PTR說明是字節操作,字操作,還是 雙字操作(具體要根據使用該條指令操作的意圖);
- 操作數是直接尋址方式的存儲器操作數,是否使用 PTR要看:指令對操作數的類型屬性要求是否與操作數的 類型屬性一致(例: PUSH 指令)或依據該條指令的操作 意圖(按照字節方式?字方式?等)。
- 在雙操作數指令中(如:MOV,ADD,SUB,CMP……)
- 方括號運算符
- 用方括號括起來的地址表達式是訪問內存操 作數常用的尋址方式,方括號的另一用途是 標注數組元素的下標,下標從0開始。
- 算術運算符、邏輯運算符、關系運算符
- 算術運算符: +, -, *, /
- 邏輯運算符: AND(與), OR(或), XOR(異或),NOT(非), SHL(左移位),SHR(右移位)
- 關系運算符: EQ(等於), NE(不等於), GT(大於),LT(小 於), GE(大於或等於),LE(小於等於)
- 注:指令匯編后,如果為真,則結果為FFFFH, 如果為假,則結果為0
- $運算符