1. 程式人生 > 其它 >20192422李俊潔 組合語言程式設計1~4章學習筆記

20192422李俊潔 組合語言程式設計1~4章學習筆記

第一章 基礎知識

1.1組合語言的一般概念

計算機程式設計語言分為三類:

a.機器語言:以二進位制數碼表示

優點:執行速度快,程式長度最短。
缺點:不便於記憶和閱讀。

b.高階語言:類似自然語言的語句來編制程式

優點:程式設計簡單。
缺點:程式效率較機器語言低。

c.組合語言

(1)定義

使用字母符號來表示機器語言的命令,用十進位制數或十六進位制
數來表示資料,這樣的計算機程式設計語言就稱為組合語言。

(2)組合語言程式與機器語言程式的關係

一條組合語言的語句與一條機器語言指令對應(一對一),組合語言程式與機器語言程式效率相同。

(3)不同型別計算機有不同的機器指令系統和組合語言描述

需要熟悉計算機的內部組成結構,但只需要掌握用匯編語言編制程式時所涉及到的那些硬體的結構和功能

1.2 學習和使用匯編語言的目的

1.學習和使用匯編語言可以從根本上認識、理解計算機的工作過程。

即更充分地利用機器硬體的全部功能,發揮機器的長處

3. 組合語言程式的效率高於高階語言程式

“效率”的含義:

程式的目的碼長度
程式執行的速度

1.3 進位計數制及其相互轉換

一. 進位計數制

使用一定個數的數碼的組合來表示數字。

一些基本含義

位權:各個位置上所表示的基本數值稱為位權, 簡稱
基數:每個數位上能使用不同數碼的個數稱為基數。

二. 各種數制間的相互轉換

1. 十進位制整數轉換為二進位制數

(1)減權定位法

(2)除基取餘法

2.十進位制小數轉換為二進位制數

(1)減權定位法

(2)乘基取整法

3. 二進位制整數轉換為十進位制數

(1)按權相加法

(2)逐次乘基相加法

4. 二進位制小數轉換為十進位制數

(1)按權相加法

(2)逐次除基相加法

5. 二進位制與八進位制和十六進位制間的轉換

對應關係:

三位二進位制數對應一位八進位制數,四位二進位制數對應一位十六進位制數。

1.4 帶符號數的表示

在一般算術表示中使用“+”和“-”來表示正數負數,而在計算機中使用“0”和“1”來表示正數負數。用“+”或“-”表示正負的數叫真值

一、原碼錶示

二進位制數的最高位表示符號,0表示正1表示負。數值部分用二進位制數絕對值表示。

二、補碼的表示

1.補碼的定義

帶符號數X的補碼錶示[X]補定義為:
[X]補=M+X (Mod M)

2.由真值、原碼變換為補碼

負數的真值變換為補碼的方法:將各位變反(0變1,1變0)然後在最低位加1.
負數的原碼變換為補碼:保持符號位不變,其餘各位變反最低位加1

3.補碼數的表示範圍

當位數為8時:
最大補碼為01111111=[+127]補
最小補碼為10000000=[-128]補

4. 補碼的加減運算

規則:
[X+Y]補=[X]補+[Y]補
[X-Y]補=[X]補-[Y]補=[X]補+[-Y]補
注:[-Y]補是對[Y]補執行一次求補運算

1.5 字元的表示

在計算機內部目前最廣泛採用的是ASCII碼

標準ASCII碼為一位元組,其中用低七位表示字元編碼,用最高位表示奇偶數驗位。

1.6 基本邏輯運算

由於狀態“0”和“1”正好與邏輯運算中的邏輯“真”和“假”對應,因此可以用“0”和“1”來表示邏輯變數的取值

1. “與”運算(AND)

“與”運算是指:僅當邏輯變數A與B都是1時,運算結果F才為1。其它情況F為0,即:0 ∧ 0 =0,0 ∧ 1 = 0,1 ∧ 0 = 0,1 ∧ 1 =1

2. “或”運算(OR)

“或”運算是指當邏輯變數A與B中,至少有一個為1時,結果F為1,其他情況F為0。即:0 ∨0=0 ,0 ∨1=1 ,1 ∨0=1 ,1 ∨1=1

3.“非”運算

“非”運算是指對邏輯變數取相反的一個邏輯值,即:1 = 0 ,0 = 1

4. “異或”運算(XOR)

“異或”運算是指:當A和B相同時(同時為1或同時為0),運算結果F為0,而不同時,F為1。即:1 ⊕ 1=0 ,1 ⊕ 0=1 0, ⊕ 1=1 0⊕, 0=0

第二章 IBM-PC微機的功能結構

2.1 IBM-PC微機基本結構

一. 微機的一般構成

五大部件:運算器、控制器、儲存器、輸入裝置和輸出裝置。

1、中央處理器CPU

概念:將運算器和控制器兩大部件整合在一個積體電路晶片上,稱為中央處理器 ,簡稱CPU,也叫微處理器
功能:分析從主儲存器取來的各條指令的功能,控制計算機各部件完成指定功能的各項操作

2、主儲存器

概念:主儲存器是用來存放程式和資料的部件。它由若干個儲存單元構成。
儲存單元:儲存單元的多少表示儲存器的容量。每個儲存單元使用一個唯一的編號來標識,稱為儲存單元的地址。
訪問規則:對每個儲存單元內容的存和取是按照地址進行訪問的。

習慣上將CPU與主儲存器合稱為主機。
在計算機中,除了主儲存器之外,一般還配置有輔助儲存器,簡稱輔存。由於它的位置是在主機之外,因此也叫做外存

3、輸入輸出裝置及介面

輸入裝置:
將外部資訊(程式、資料和命令)送入計算機。包括鍵盤、滑鼠等。
輸出裝置:
將計算機處理後的結果轉換為人或其它系統能識別的資訊形式向外輸出。如顯示器、印表機等。
有的裝置既具有輸入功能又具有輸出功能
磁碟、磁帶、觸控顯示屏等。
I/O介面:主機與I/O裝置之間設定的邏輯控制部件。通過它實現主機與I/O裝置間的資訊傳送。

4、系統匯流排

包括地址匯流排資料匯流排控制匯流排三組。它們分別用於傳送不同的資訊。

二、 Intel 8086/8088 CPU的功能結構

組合語言程式是由一系列的指令(指令序列)構成,指令是構成組合語言程式的最基本單位
CPU執行指令序列就是重複執行以下兩個步驟:
從儲存器中取指令
執行指令規定的操作

1. 序列方式

缺點:採用序列工作方式的計算機其執行速度較慢

2.指令流水線方式

優點:採用指令流水線工作方式的計算機具有較高的工作效率。

(1)執行單元EU

分析與執行指令

(2)匯流排介面單元BIU

負責CPU與儲存器、I/O的資訊傳送

2.2 Intel 8086/8088CPU暫存器結構及其用途

一、通用暫存器

Intel 8086/8088有8個16位通用暫存器

1. 資料暫存器

它包括AX、BX、CX和DX四個暫存器,每一個既可以是16位暫存器,也可以分成兩個8位暫存器使用。

2. 指標暫存器

堆疊指標SP和基址指標BP,一般被用來存放16位地址,在形成20位的實體地址時常被作為偏移量使用。
SP指標:在進行堆疊操作時,被隱含使用,被用來指向
堆疊頂部單元.
BP指標:被用來指向堆疊段內某一儲存單元。

3. 變址暫存器

有兩個16位的變址暫存器SI和DI,一般被用來作地址指標.
SI:源變址暫存器
DI:目的變址暫存器

二、段暫存器

段基址:每個儲存段用一個段暫存器來指明該段的起始位置。

注:CPU在訪問儲存器時必須指明兩個內容

(1)所訪問的儲存單元屬於哪個段,即指明使用的段暫存器

(2)該儲存單元與段起始地址(段基址)的相距多少,即偏移量

三、指令指標IP

概念:當CPU從記憶體中取出一條指令後,IP內容自動修改為指向下一條指令。

四、標誌暫存器

概念:用來反映CPU在程式執行時的某些狀態,如是否有進位、奇偶性、結果的符號、結果是否為零等等。
:8086/8088CPU中標誌暫存器的長度為16位,但只定義了其中的9位。

1. 進位標誌位CF

2. 奇偶標誌位PF

3. 輔助進位標誌位AF

4. 零值標誌位ZF

5. 符號標誌位SF

6. 溢位標誌位OF

7. 單步標誌位TF(Trace Flag)

8. 中斷允許標誌位IF

9. 方向標誌位DF

2.3 儲存器組織結構

1. 儲存器是由若干個儲存單元構成

2. 每個儲存單元存放相同長度的二進位制數。

3. 每個儲存單元有一個唯一的地址編號——地址

4. 任何兩個相鄰位元組單元就構成一個字單元.

5、在定義一個地址時必須指出是位元組或字型別屬性

二、儲存器的段結構

1.每個段最大長度為64K(65536)個位元組單元組成。

2. 每個段的基址(段基址)必須是一個小節的首址。(注:段基址為一個段的起始地址)

3. 邏輯段在物理儲存器中可以是鄰接的、間隔的、部分重疊的和完全重疊的等4種情況。

4. 在任一時刻,一個程式只能訪問4個當前段中的內容。

4個段分別是程式碼段、資料段、堆疊段和附加段,稱為當前段。

三、 邏輯地址與實體地址及對應關係

1. 實體地址

在1MB的儲存空間中,每個儲存單元的實體地址是唯一的,它就是該儲存單元的20位地址。
:CPU與儲存器之間的任何資訊交換都使用實體地址

2. 邏輯地址

一個邏輯地址包括兩個部分:段基值和偏移量
段基值:存放在某一個段暫存器中,是一個邏輯段的起始單元地址(段基址)的高16位。
偏移量:表示某個儲存單元與它所在段的段基址之間的位元組距離。
邏輯地址的表示方法:
段基值:偏移量

3.邏輯地址轉換為實體地址

轉換方法:將邏輯地址的段基值左移4位,形成20位的段基址(低位為0)然後與16位的偏移量相加,結果即為20位的實體地址。

4.邏輯地址的來源

(1)允許替代來源也叫做段超越,它表示了段基值除使用隱含的段暫存器外是否可以指定其它段暫存器來提供。

(2)有效地址EA,它表示根據指令所採用的定址方式(下一章介紹)計算出來的段內偏移量。

2.4 堆疊及其操作方法

堆疊的用途:主要用於暫存資料以及在過程呼叫或處理中斷時儲存斷點資訊

一、堆疊的構造

專用堆疊儲存器:按堆疊的工作方式專門設計的儲存器
軟體堆疊:由程式設計人員用軟體在記憶體中劃出的一塊儲存區作為堆疊來使用。
:堆疊的一端是固定的,稱為棧底。棧底是堆疊儲存區的最大地址單元。另一端是浮動的,稱為棧頂
指標sp:SP的內容始終指向棧頂單元,堆疊中資料進出都由SP來控制。
堆疊存取資料規則:“先進後出FILO”。

二、8086/8088堆疊的組織

頂由堆疊指標SP指示。SP中內容始終表示堆疊段基址與棧頂之間的距離(位元組數)。當SP內容為最大(初始)值時,表示堆疊為空。而當(SP)=0時,表示堆疊全滿.
當SP被初始化時,指向棧底+2單元,其值就是堆疊的長度。

三、堆疊操作

1.設定堆疊:主要是對堆疊段暫存器SS和堆疊指標SP賦值

2.進棧PUSH:是把資料存入堆疊。由指令PUSH或者由機器自動實現,可以將通用暫存器、段暫存器或字儲存單元的內容壓入堆疊頂部。

進棧的執行過程

(1)首先將堆疊指標SP減2,即指向一個空的堆疊字單元 SP<=(SP)-2
(2)將要儲存的內容(暫存器或儲存單元的內容)送入SP指向的字單元中。(SP)<=資料

3.出棧POP:出棧操作由POP指令或機器自動實現,它從堆疊頂部彈出一個字到通用暫存器、段暫存器或字儲存單元

出棧的操作過程:

(1)將SP指向的字單元(即棧頂字單元)內容送往指定的暫存器或儲存器。即:暫存器/儲存器<=((SP))
(2)堆疊指標SP內容加2,即:SP<=(SP)+2

第三章 定址方式與指令系統

3.1 定址方式

一條指令通常由兩大部分構成:

操作碼:表示該指令應完成的具體操作,如加法、減法、乘法、移位等等。

運算元: 表示該指令的操作物件。如移位操作的被移位數,加法操作的加數等等。

定址方式:尋找指令中所需運算元的各種方法,也就是提供指令中運算元的存放資訊的方式。

(1)立即數運算元——運算元在指令程式碼中提供

(2)暫存器運算元——運算元在CPU的通用暫存器或段暫存器中

(3)儲存器運算元——運算元在記憶體的儲存單元中

(4)I/O埠運算元——運算元在輸入/輸出介面的暫存器中

1.立即數定址:立即數定址方式的指令中,所需運算元直接包含在指令程式碼中,這種運算元稱為立即數。

:立即數只能作為源運算元,而不能作為目的運算元。

2.暫存器定址:暫存器定址方式是指指令中所需的運算元在CPU的某個暫存器中。暫存器可以是8位或16位通用暫存器,或者是段暫存器。

:由於存取暫存器運算元完全在CPU內部進行,不需要匯流排週期,所以執行速度很快

一個儲存單元邏輯地址表示形式:

段基值:偏移量
段基值:由某個段暫存器提供.
偏移量:表示了該儲存單元與段起始地址之間的距離,也叫做有效地址EA

有效地址EA是以下三個地址分量的幾種組合,由CPU的執行單元EU計算出來的。

(1)位移量:位移量是指令中直接給出的一個8位或16位數。
(2)基址:由基址暫存器BX或基址指標BP提供的內容。
(3)變址:由源變址暫存器SI或目的變址暫存器DI提供的內容

:位移量、基址和變址三個地址分量組合時,若有兩個或兩個以上分量時,將進行以2^16為模的十六位加法運算。

3.直接定址:在直接定址方式的指令中,運算元的有效地址EA只有位移量地址分量。

:用常數表示時,必須用方括號括起來。段暫存器不能省略。

4.暫存器間接定址:是事先將偏移量存放在某個暫存器(BX、BP、SI或DI)中,這些暫存器就如同一個地址指標。在程式執行期間,只要對暫存器內容進行修改,就可以實現用同一條指令實現對不同儲存單元進行操作。

5.基址定址/變址定址

運算元的有效地址EA等於基址分量或變址分量加上指令中給出的位移量。

指令中使用BX或BP時為基址定址

指令中使用SI或DI時為變址定址

6.基址變址定址

運算元的有效地址是三個地址分量之和,即:

EA=基址+變址+位移量

注:

當基址選用BX時隱含使用段暫存器DS,而選用BP時則隱含使用段暫存器SS

7.串操作定址方式

尋找源運算元時,隱含使用SI作為地址指標。

尋找目的串時,隱含使用DI作為地址指標。

串操作完成之後,自動對SI和DI進行修改,使它們指向下一個運算元

8. I/O埠定址

儲存器編址方法:

將I/O埠視為儲存器的一個單元,對埠的訪問就如同訪問儲存單元一樣。

特點: 程式設計靈活,但需要佔用儲存地址空間

I/O埠編址方法

I/O埠的地址與儲存器地址分開,並使用專門的輸入指令和輸出指令。定址方式有如下兩種:

(1) 直接埠定址

在指令中直接給出埠地址,埠地址一般採用2位十六進位制數,也可以用符號表示。

(2)暫存器間接埠定址

暫存器間接埠定址:把I/O埠的地址先送到DX中,用DX作間接定址暫存器。

3.2 指令系統

一種計算機所能執行的各種型別的指令的集合稱為該計算機的指令系統

Intel8086/8088CPU指令系統的指令可以分為六大類:

1.傳送類指令

2.算術運算類指令

3.位操作類指令

4.串操作類指令

5.程式轉移類指令

6.處理器控制類指令

從指令的格式劃分,一般可以分為三種:

1.雙運算元指令:OPR DEST SRC

2.單運算元指令:OPR DEST

3.無運算元指令:OPR

對於無運算元指令,包含兩種情況:

(1)指令不需要運算元,如暫停指令HLT。

(2)在指令格式中,沒有顯式地指明運算元,但是它隱含指明瞭運算元的存放地方,如指令PUSHF。

一、傳送類指令:傳送類指令的作用是將資料資訊或地址資訊傳送到一個暫存器或儲存單元中

1.通用資料傳送指令

指令格式:MOV DEST,SRC

作用:將源運算元指定的內容傳送到目的運算元,即DEST<=(SRC)

MOV指令可以是位元組資料傳送也可以是字資料傳送,但是源運算元和目的運算元的長度必須一致。

MOV指令對標誌暫存器的各位無影響,MOV指令可以分為以下幾種情況:

(1)立即數傳送到通用暫存器或儲存單元:立即數只能作為源運算元,立即數不能傳送給段暫存器。
(2)暫存器之間的傳送:段暫存器CS只能作源運算元,不能作目的運算元。
(3)暫存器與儲存單元之間傳送

總結:

(1)立即數只能作源運算元,且它不能傳送給段暫存器。

(2)段暫存器CS只能作源運算元,段暫存器之間不能直接傳送。

(3)儲存單元之間不能直接傳送資料

(4)MOV指令不影響標誌位

2.交換指令

指令格式:XCHG DEST,SRC

作用:源運算元和目的運算元兩者內容相互交換,即:(DEST)<=>(SRC)。

3.標誌傳送指令:對標誌暫存器進行存取的指令有4條,它們都是無運算元指令,即指令隱含指定標誌暫存器AH暫存器堆疊為運算元。

(1)取標誌暫存器指令

指令格式:LAHF

作用:將標誌暫存器的低8位送入AH暫存器,即將標誌SF、ZF、AF、PF和CF分別送入AH的第7、6、4、2、0位,而AH的第5、3、1位不確定。

(2)儲存標誌暫存器指令

指令格式:SAHF

作用:將暫存器AH中的第7、6、4、2、0位分別送入標誌暫存器的SF、ZF、AF、PF和CF各標誌位。而標誌暫存器高8 位中的各標誌位不受影響

(3)標誌進棧指令

指令格式:PUSHF

作用:先將堆疊指標SP減2,使其指向堆疊頂部的空字單元,然後將16位標誌暫存器的內容送SP指向的字單元。

(4)標誌出棧指令

作用:將由SP指向的堆疊頂部的一個字單元的內容送

入標誌暫存器,然後SP的內容加2.指令格式:POPF

4.地址傳送指令:這類指令有3條,它們的作用是將儲存單元的地址送暫存器

(1)裝入有效地址

格式:LEA DEST,SRC

其中:源運算元SRC必須是一個位元組或字儲存器運算元(地址),DEST必須是一個16位通用暫存器。

作用:將SRC儲存單元地址中的偏移量,即有效地址EA傳送到一個16位通用暫存器中

(2)裝入地址指標指令

格式:LDS DEST,SRCLES DEST,SRC

其中:DEST是任意一個16位通用暫存器。SRC必須是一個儲存器運算元。

作用:把SRC儲存單元開始的4個位元組單元的內容(32位地址指標)送入DEST通用暫存器和段暫存器DS(LDS指令)或ES(LES指令),其中低字單元內容為偏移量送通用暫存器,高字單元內容為段基值送DS或ES

二、算術運算類指令

1.加法指令

功能:目的運算元和源運算元相加,其和存放到目的運算元中,而源運算元內容保持不變,即DEST<=(DEST)+(SRC)

2.帶進位加法指令

指令格式:ADC,DEST,SRC該指令的功能與ADD基本相同,所不同的是其結果還要加上進位標誌CF的值,即:DEST<=(DEST)+(SRC)+CF。根據相加的結果設定標誌暫存器中的CF、PF、AF、ZF、SF和OF

注:參加運算的進位CF是本條指令執行之前的值。

3.加1指令

指令格式:INC DEST

功能:該指令為單運算元指令,其功能是將目的運算元加1,並送回到目的運算元,即:DEST<=(DEST)+1

4.減法指令

指令格式:SUB DEST,SRC

功能:目的運算元的內容減去源運算元的內容,結果送入目的運算元,源運算元中內容保持不變。即:DEST<=(DEST)-(SRC)

5.帶借位減法

指令格式:SBB DEST,SRC

功能:與SUB指令基本相同,不同的是在兩個運算元相減後再減去進位標誌CF的值。即:DEST<=(DEST)-(SRC)-CF。

注:該CF的值是本條指令執行前的結果

6.減1指令

指令格式:DEC DEST

該指令為單運算元指令,將目的運算元的內容減1後,送回到目的運算元。即:DEST<=(DEST)-1

7.求負數指令

指令格式:NEG DEST

功能:用零減去目的運算元的內容,並送回目的運算元,即:DEST<=0-(DEST)

三、位操作類指令

1.邏輯運算指令:邏輯運算指令共有4條。

邏輯“與”指令 AND DEST,SRC

邏輯“或”指令 OR DEST,SRC

邏輯“異或”指令 XOR DEST,SRC

邏輯“非”指令 NOT DEST

注:DEST和SRC可以是8位或16位的通用暫存器或儲存器運算元,但兩者不能同時為儲存器運算元,SRC可以為立即數

2.測試指令

指令格式:TEST DEST,SRC

功能:與AND指令相似,實現源運算元與目的運算元進行按位“邏輯與”運算,對標誌位的影響與AND指令相同,但運算的結果不送入目的運算元,即目的運算元內容也將保持不變。

3.移位/迴圈移位指令:這一類指令共有8條,分為3類。

(1)算術移位

算術左移 SAL DEST,COUNT
算術右移 SAR DEST,COUNT

(2)邏輯移位

邏輯左移 SHL DEST,COUNT
邏輯右移 SHR DEST,COUNT

(3)迴圈移位

小迴圈

迴圈左移 ROL DEST,COUNT
迴圈右移 ROR DEST,COUNT

大迴圈

帶進位迴圈左移 RCL DEST,COUNT
帶進位迴圈右移 RCR DEST,COUNT

注:這8條指令具有以下幾個共同點:

(1)DEST為操作物件,它可以是位元組或字運算元,可以是通用暫存器或儲存器運算元。當移位次數為1時,使用常數1或暫存器CL。

(2)COUNT用來決定移位/迴圈的位數,即確定移位的次數。當移位次數大於1時,必須使用暫存器CL。

(3)在執行移位時,根據指令不同,每移位一次,最高位(左移)或最低位(右移)都要送到進位標誌CF。

(4)前4條移位指令根據移位結束後修改標誌位CF、PF、ZF、SF和OF,而AF不確定。而後4條迴圈移位指令根據移位結束後的結果僅修改CF和OF。

四、處理器控制類指令

1.標誌位操作指令:它們都是無運算元指令,運算元隱含為標誌暫存器的某個標誌位。能直接操作的標誌位有CF、IF和DF。

(1)清除進位標誌 CLC ;置CF為0

(2)置1進位標誌 STC ;置CF為1

(3)進位標誌取反 CMC ;CF的值取反

(4)清除方向標誌 CLD;置DF為0

(5)置1方向標誌 STD;置DF為1

(6)清除中斷標誌 CLI;置IF為0

(7)置1中斷標誌 STI;置IF為1

2、與外部事件同步的指令

HLT ;暫停指令

WAIT ;等待指令

ESC ;外部協處理器指令字首

LOCK ;匯流排鎖定指令

3、空操作指令: NOP執行一次NOP佔用CPU三個時鐘週期,它不改變任何暫存器或儲存單元內容,主要用於延時。

3.3 指令編碼

彙編:將組合語言程式轉換為機器語言程式的過程

彙編程式:在計算機中實現彙編過程的系統程式

彙編指令的編碼格式有四種基本格式

1.雙運算元指令編碼格式

2.單運算元指令編碼格式

3.與AX或AL有關的指令編碼格式

4.其它指令編碼格式

一、雙運算元指令編碼格式

一個運算元在暫存器中,另一運算元在暫存器儲存器中。

目的運算元在暫存器或儲存器中,源運算元是立即數

整個指令編碼可以包含4個部分

1.操作特徵部分:這部分為指令編碼的首位元組,它又分為以下三個段。

(1)OPCODE:操作碼欄位

該欄位長度為6bit。它表示了該指令所執行的功能和兩個運算元的來源。

(2)方向欄位d

該欄位與第2部分定址特徵一起來決定源運算元和目的運算元的來源。

(3)字/位元組欄位W

當W=1時,表示兩運算元長度為字;當W=0時,表示兩運算元長度為位元組。

2.定址特徵部分

它與操作特徵部分的方向欄位d結合,指定兩個運算元分別使用什麼定址方式,及使用哪個暫存器。

它包括MOD、REG和R/M三個欄位,REG欄位確定一個運算元,而MOD和R/M欄位確定另一個運算元。

當d=1時,則目的運算元由REG欄位確定,而源運算元由MOD和R/M欄位確定。

當d=0時,則目的運算元由MOD和R/M 欄位確定,而源運算元由REG欄位確定。

(1)REG欄位

由REG欄位確定的一個運算元是某一通用暫存器的內容,即使用的是暫存器定址方式。第一部分中的W欄位決定運算元是字或是位元組。

(2)定址方式欄位MOD和暫存器/儲存器欄位R/M

這兩個欄位共同確定一個運算元。該運算元可以在暫存器中,也可以在儲存器中MOD、R/M和W欄位共同確定運算元的定址方式和所使用的暫存器

3.位移量部分

三種情況:

沒有位移量

1位元組位移量disp8

2位元組位移量disp16

4.立即數部分

如果指令的源運算元為立即數,則指令編碼中包含有該部分。它總是位於指令編碼的最後1~2位元組

二、單運算元指令編碼格式

這種編碼格式適用於只有一個運算元的指令,如INC、DEC、移位/迴圈等指令。指令編碼為2~3位元組

操作特徵部分

包括OPCODE 、V和W三個欄位,其中V欄位只有移位/迴圈指令中才有該欄位。其它指令中沒有該欄位。

V=0時,指令中使用常數1作為移位或迴圈次數。

V=1時,指令中使用暫存器CL作移位次數。

:由於單運算元指令中只有一個運算元,因此定址特徵部分就不需要REG欄位,而該欄位被用作輔助操作碼

三、與AX或AL有關的指令編碼格式

採用這種編碼格式的指令,除一個運算元隱含指定為AX/AL外,另一個運算元可以是立即數或儲存單元。

立即數:則編碼中應有1~2位元組的立即數

儲存單元:只能使用直接定址方式,位移量由disp欄位給出。

四、其它指令編碼格式

標誌位操作指令堆疊操作指令等。這些指令的編碼格式一般只有一個位元組

第四章 組合語言程式格式

4.1 組合語言語句種類及其格式

組合語言的語句可以分為指令語句偽指令語句

一、指令語句

每一條指令語句在彙編時都要產生一個可供CPU執行的機器目的碼,它又叫可執行語句

一條指令語句最多可以包含4個欄位

1.標號欄位

標號是可選欄位,它後面必須有“:”。標號是一條指令的符號地址,代表了該指令的第一個位元組存放地址

標號一般放在一個程式段或子程式的入口處,控制程式的執行轉到該程式位置。

在轉移指令或子程式呼叫指令中,可直接引用這個標號。

該欄位是一條指令的必選項,它表示這條語句要求,如MOV、ADD、SHL等。

2.指令助記符欄位

有些指令還可以在指令助記符的前面加上字首,實現一定的附加操作。如串操作指令前所加的重複字首REP。

一條指令可以有一個運算元、兩個運算元或者無運算元。

3.運算元欄位

如ADD、MOV指令需要兩個運算元,INC、NOT指令只需一個運算元,而CLC指令不需要運算元。

4.註釋欄位

註釋欄位為可選項,該欄位以分號“;”開始。它的作用是為閱讀程式的人加上一些說明性內容

註釋欄位不會產生機器目的碼,它不會影響程式和指令的功能。

註釋欄位可以是一條指令的後面部分,也可以是整個語句行。

二、偽指令語句

偽指令語句又叫命令語句。

偽指令本身並不產生對應的機器目的碼。它僅僅是告訴彙編程式對其後面的指令語句和偽指令語句的運算元應該如何處理。

一條偽指令語句可以包含四個欄位。

1.符號名欄位

該欄位為可選項。根據偽指令的不同,符號名可以是常量名、變數名、過程名、結構名和記錄名等等。

一條偽指令語句的符號名可以作其它偽指令語句或指令語句的運算元,這時它表示一個常 量或儲存器地址

:符號名後面沒有冒號“:”,這是與指令語句的重要區別。

2.偽指令符欄位

該欄位是偽指令語句的必選項,它規定了彙編程式所要完成的具體操作。本章後面的章節將對各種偽指令作詳細介紹。

3.運算元欄位

該欄位是否需要,以及需要幾個是由偽指令符欄位來決定。

運算元可以是一個常數(二進位制、十進位制、十六進位制等)、字串、常量名、變數名、標號和一些專用符號(如BYTE、FAR、PARA等)。

4.註釋欄位

註釋欄位為可選項,該欄位必須以分號開始。其作用與指令語句的註釋欄位相同。

三、識別符號

規則:

1.字元的個數為1~31個;

2.第一個字元必須是字母、問號、@或下劃線“_”這4種字元之一;

3.從第二個字元開始,可以是字母數字、@ 、 “_”或問號“?”;

4.不能使用屬於系統專用的保留字。

保留字: CPU中各暫存器名(如AX、CS等),指令助記符(如MOV、ADD),偽指令符(如SEGMENT、DB)、表示式中的運算子(如GE、EQ)以及屬性操作符(如PTR、OFFSET等)。

4.2 組合語言資料

資料是指令偽指令語句中運算元的基本組成部分。一個數據由數值屬性兩部分構成。在說明資料時不僅要指定其數值,還需說明它的屬性,比如是位元組資料還是字資料。在組合語言中常用的資料形式有:常數變數標號

一、常數

常數在彙編期間其值已完全確定,並且在程式執行過程中,其值不會發生變化

常數有以下幾種形式:

1.二進位制數:以字母B結尾,如01001001B

2.八進位制數:以字母O或Q結尾,如631Q 254O

3.== 十進位制數:以字母D==結尾,或者沒有結尾字母。如2007D、2007。

4. 十六進位制數:以字母H結尾,如3FEH,如果常數的第一個數字為字母,為了與識別符號加以區別,必須在其前面冠以數字“0”。

5.實數。一般格式為:±整數部分• 小數部分E ±指數部分

6.字串常數:用引號(單引號或雙引號)括起來的一個或多個字元,這些字元以它的ASCII碼值儲存在記憶體。

常數在程式中可以用在以下幾種情況:

(1)作指令語句的源運算元

(2)在指令語句的直接定址方式、變址(基址)定址方式或基址變址定址方式中作位移量

(3)在資料定義偽指令中使用。

二、變數

變數用來表示存放資料的儲存單元,這些資料在程式執行期間可以被改變 。

程式中以變數名的形式來訪問變數,因此,可以認為變數名就是存放資料的儲存單元地址

1.變數的定義與預置

定義變數就是給變數在記憶體中分配一定的儲存單元。也就是給這個儲存單元賦與一個符號名,即變數名,同時還要將這些儲存單元預置初值

注:

當變數被定義後,就具有了以下三個屬性:

(1)段屬性

它表示變數存放在哪一個邏輯段中。

(2)偏移量屬性(OFFSET)

它表示變數所在位置與段起始點之間的位元組數。

補:段屬性和偏移量屬性就構造了變數的邏輯地址

(3)型別屬性

它表示變數佔用儲存單元的位元組數。其中DB偽指令定義的變數為位元組,DW定義的變數為字,DD定義的為雙字(4位元組),DQ定義的為4字,DT定義的為5字。

在變數的定義語句中,給變數賦初值的表示式可以使用下面4種形式:

(1)數值表示式

(2)?表示式

(3)字串表示式

對於DW偽指令可以給兩個字元組成的字
符串分配兩個位元組儲存單元。
對於DD偽指令,只能給兩個字元組成的字串分配4個位元組單元。
==兩個字元存放在較低地址的兩個位元組單元中。存放順序與DW偽指令相同,而較高地址的兩個位元組單元存放0。
:DW和DD偽指令不能用兩個以上字元構成的字串賦初值==,否則將出錯。

(4)DUP表示式

2.變數的使用

(1)在指令語句中引用

指令語句中直接引用變數名就是對其儲存單元的內容進行存取.當變量出現在變址(基址)定址或基址變址定址的運算元中時表示取用該變數的偏移量

(2)在偽指令語句中引用

三、標號

標號寫在一條指令的前面,它就是該指令在記憶體的存放地址的符號表示,也就是指令地址的別名。標號主要用在程式中需要改變程式的執行順序時,用來標記轉移的目的地,即作轉移指令的運算元

每個標號具有三屬性

(1)段屬性(SEG)

它表示該標號所代表的地址在哪個邏輯段中,即段基值

(2)偏移量屬性(OFFSET)

它表示該標號所代表的地址在段內與段起點間的位元組數,即地址的偏移量

(3)距離屬性(也叫型別屬性)

它表示該標號可以被段內還是段間的指令呼叫。
NEAR(近):該標號只能作段內轉移,也就是說只能是與該標號所指指令同在一個邏輯段的轉移指令和呼叫指令才能使用它。
FAR(遠):該標號可以被非本段的轉移和呼叫指令使用。

標號的距離屬性可以有兩種方法來指定:

a.隱含方式

當標號加在指令語句前面時,它隱含為NEAR屬性。

b.用LABEL偽指令給標號指定距離屬性

格式: 標號名 LABEL 型別
型別為NEAR或FAR。該語句應與指令語句連用
:LABEL偽指令還可以用來定義變數的屬性,即改變一個變數的屬性,如把字變數的高低位元組作為位元組變數來理。

4.3 符號定義語句

一、等值語句

語句格式:符號名 EQU 表示式

功能:用符號名來表示EQU右邊的表示式。後面的程式中一旦出現該符號名,彙編程式將把它替換成該表示式。表示式可以是任何形式。如:

1.常數或數值表示式

2.地址表示式

3.變數、暫存器名或指令助記符

二、等號語句

格式:符號名=表示式

等號語句與等值語句具有相同的作用。但等號語句可以對一個符號進行多次定義

等值語句與等號語句都不會為符號分配儲存單元。因此所定義的符號沒有段、偏移量和型別等屬性

4.4 表示式與運算子

表示式是指令或偽指令語句運算元的常見形式。它由常數、變數、標號通過操作運算子連線而成。

:任何表示式的值在程式被彙編的過程中進行計算確定,而不是到程式執行時才計算。

操作運算子可以分為以下五類

一、算術運算子

1.運算子“+”和“-”也可作單目運算子,表示數的正負。

2.使用“+”、“-”、“*”、和“/”運算子時,參加運算的數和運算結果都是整數。

3.“/”運算為取商的整數部分,而“MOD”運算取除法運算的餘數。

4. “SHR ”和“SHL ”為邏輯移位運算子

移位運算子與移位指令區別。 移位運算子的操作物件是某一具體的數(常數),在彙編時完成移位操作。而移位指令是對一個暫存器或儲存單元內容在程式執行時執行移位操作

5.下標運算子“[ ]”具有相加的作用

一般使用格式: 表示式1 [表示式2]
作用:將表示式1與表示式2的值相加後形成一個儲存器運算元的地址

二、邏輯運算子

邏輯運算子有NOT、AND、OR和XOR等四個,它們執行的都是按位邏輯運算

三、關係運算符

關係運算符包括:

EQ(等於)、NE(不等於)、LT(小於)、 LE(小於等於)、GT(大於)、GE(大於等於

關係運算符用來比較兩個表示式的大小。關係運算符比較的兩個表示式必須同為常數或同一邏輯段中的變數。

如果是常量的比較,則按無符號數進行比較;如果是變數的比較,則比較它們的偏移量的大小。

關係運算的結果只能是“真”(全1)或“假”(全0

四、數值返回運算子

1.SEG運算子

作用:取變數或標號所在段的段基值

2.OFFSET運算子

作用:取變數或標號在段內的偏移量

3.TYPE運算子

作用:取變數或標號的型別屬性,並用數字形式表示。對變數來說就是取它的位元組長度

4.LENGTH運算子

作用:用於取變數的長度。

5.SIZE運算子

作用:作用於變數,SIZE取值等於LENGTH和TYPE兩個運算子返回值的乘積

五、屬性修改運算子

1.PTR運算子

使用格式: 型別 PTR 地址表示式

作用: 將地址表示式所指定的標號、變數或用其它形式表示的儲存器地址的型別屬性修改為“型別”所指的值。型別可以是BYTE、WORD、DWORD、NEAR和FAR。這種修改是臨時的,只在含有該運算子的語句內有效。

2.HIGH/LOW運算子

使用格式:

HIGH 表示式
LOW 表示式

這兩個運算子用來將表示式的值分離出高位元組低位元組

如果表示式為一個常量,則將其分離成高8位和低8位;

如果表示式是一個地址(段基值或偏移量)時,則分離出它的高位元組和低位元組。

注:HIGH/LOW運算子不能用來分離一個變數、暫存器或儲存器單元的高位元組與低位元組。

3、THIS運算子

THIS運算子一般與等值運算子EQU連用,用來定義一個變數或標號的型別屬性。所定義的變數或標號的段基值偏移量與緊跟其後的變數或標號相同

六、運算子的優先順序

彙編程式在計算表示式時,按以下規則進行運算。

先執行優先級別高的運算,再算較低級別運算;

相同優先級別的操作,按照在表示式中的順序從左到右進行;

可以用圓括號改變運算的順序。

4.5 程式的段結構

8086/8088在管理記憶體時,按照邏輯段進行劃分,不同的邏輯段可以用來存放不同目的的資料。在程式中使用四個段暫存器CS,DS,ES和SS來訪問它們。

在源程式設計時,使用偽指令來定義和使用這些邏輯段

一、段定義偽指令

偽指令SEGMENT和ENDS用於定義一個邏輯段。使用時必須配對,分別表示定義的開始結束

段定義偽指令語句各部分的作用如下:

1、段名

段名是由使用者自己任意選定的,符合識別符號定義規則的一個名稱。

一個段的開始與結尾用的段名必須一致

2、定位型別

定位型別用於決定段的起始邊界,即第一個可存放資料的位置(不是段基址)。它可以有4種取值。

(1)PAGE: 表示該段從一個頁面的邊界開始,由於一個頁面為256個位元組,並且頁面編號從0開始,因此,PAGE定位型別的段起始地址的最後8位二進位制數一定為0,即以00H結尾的地址。

(2)PARA:表示該段從一個小節的邊界開始,如果使用者未選定位型別,則預設為PARA。

(3)WORD:表示該段從一個偶數字節地址開始,即段起始單元地址的最後一位二進位制數一定是0

(4)BYTE:表示該段起始單元地址可以是任一地址值。

注:定位型別為PAGE和PARA時,段起始地址與段基址相同。定位型別為WORD和BYTE時,段起始地址與段基址可能不同

3、組合型別

組合型別說明符用來指定段與段之間的連線關係和定位

它有六種取值選擇。

(1)若未指定組合型別,表示本段與其它段無連線關係。在裝入記憶體時,本段有自己的物理段,因此有自己的段基址

(2)PUBLIC:在滿足定位型別的前提下,將與該段同名的段鄰接在一起,形成一個新的邏輯段,共用一個段基址。段內的所有偏移量調整為相對於新邏輯段的段基址。

(3)COMMON: 產生一個覆蓋段。在多個模組連線時,把該段與其它也用COMMON說明的同名段置成相同的段基址,這樣可達到共享同一儲存區。共享儲存區的長度由同名段中最大的段確定。

(4)STACK:把所有同名段連線成一個連續段,且系統自動對SS段暫存器初始化為該連續段的段基址。並初始化堆疊指標SP。

(5)AT表示式:表示本段可定位在表示式所指示的小節邊界上。表示式的值也就是段基值。

(6)MEMORY:表示本段在儲存器中應定位在所有其它段之後的最高地址上。如果有多個用MEMORY說明的段,則只處理第一個用MEMORY說明的段。其餘的被視為COMMON

4.類別名:類別名為某一個段或幾個相同型別段設定的型別名稱。

類別名必須用單引號引起來。所用字串可任意選定,但它不能使用程式中的標號、變數名或其它定義的符號。

在定義一個段時,段名是必須有的項,而定位型別、組合型別和類別名三個引數是可選項。各個引數之間用空格分隔。各引數之間的順序不能改變

注:在進行程式設計時,如果程式不大,一般只需要定義三個段就可以了。

二、段定址偽指令

段定址偽指令ASSUME的作用是告訴彙編程式,在處理源程式時,定義的段與哪個暫存器關聯

ASSUME並不設定各個段暫存器的具體內容,段暫存器的值是在程式執行時設定的

格式

ASSUME段暫存器名:段名,段暫存器名:段名,......

三、段暫存器的裝入

段暫存器的初值(段基值)裝入需要用程式的方法來實現。

1、DS和ES的裝入

在程式中,使用資料傳送語句來實現對DS和ES的裝入。

2、SS的裝入:SS的裝入有兩種方法

(1)在段定義偽指令的組合型別項中,使用STACK引數,並在段定址偽指令ASSUME語句中把該段與SS段暫存器關聯。

(2)如果在段定義偽指令的組合型別中,未使用STACK引數,或者是在程式中要調換到另一個堆疊,這時,可以使用類似於DS和ES的裝入方法。

3、CS的裝入

CPU在執行指令之前根據CS和IP的內容來從記憶體中提取指令,即必須在程式執行之前裝入CS和IP的值。因此,CS和IP的初始值就不能用可執行語句來裝入。

:裝入CS和IP一般有兩種情況

(1)由系統軟體按照結束偽指令指定的地址裝入初始的CS和IP

格式: END 起始地址

:END偽指令的作用是標識源程式結束和指定程式執行時的起始地址

(2)在程式執行期間,當執行某些指令時,CPU自動修改CS和IP,使它們指向新的程式碼段

4.6 過程定義偽指令(PROC/ENDP)

在程式設計過程中,常常將具有一定功能的程式段設計成一個子程式。

相關概念

過程名:

子程式的名稱,它被用作過程呼叫指令CALL的目的運算元。它類同一個標號的作用。具有段、偏移量和距離三個屬性。而距離屬性使用NEAR和FAR來指定,若沒有指定,則隱含為NEAR

:NEAR過程只能被本段指令呼叫,而FAR過程可以供其它段的指令呼叫。每一個過程中必須包含有返回指令RET,其作用是控制CPU從子程式中返回到呼叫該過程的主程式。

4.7 當前位置計數器$與定位偽指令ORG(Origin)

彙編程式在彙編源程式時,每遇到一個邏輯段,就要為其設定一個位置計數器,它用來記錄該邏輯段中定義的每一個數據或每一條指令在邏輯段中的相對位置

在源程式中,使用符號$來表示位置計數器的當前值。因此,$被稱為當前計數器。它位於不同的位置具有不同的值。

定位偽指令ORG--用來改變位置計數器的值。

格式: ORG 數值表示式

作用:將數值表示式的值賦給當前位置計數器$。ORG語句為其後的資料或指令設定起始偏移量

:表示式的值必須為正值。表示式中也可以包含有當前位置計數器的現行值$。

4.8 標題偽指令TITLE

語句格式: TITLE 標題名

作用:給所在程式指定一個標題。字元個數不能超過60

4.9 從程式返回作業系統的方法

一、使用程式段字首PSP(Program Segment Prefix)實現返回

DOS系統將一個.EXE檔案(可執行檔案)裝入記憶體時,在該檔案的前面生成一個程式段字首PSP,其長度為=100H位元組。同時讓DS和ES都指向PSP的開始,而CS指向該程式的程式碼段,即第一條可執行指令

為了使程式執行完後,正確返回DOS,需要做以下三個操作:

1. 將使用者程式編製成一個過程,型別為FAR;

2. 將PSP的起始邏輯地址壓棧,即將INT 20H指令的地址壓棧;

3. 在使用者程式結尾處,使用一條RET指令。執行該指令將使儲存在堆疊中的PSP的起始地址彈出到CS和IP中。

二、使用DOS系統功能呼叫實現返回

執行DOS功能呼叫4CH,也可以控制使用者程式結束,並返回DOS作業系統

程式結束時,使用兩條指令:

MOV AH,4CH

INT 21H