1. 程式人生 > 其它 >20192406樑健組合語言前四章學習筆記

20192406樑健組合語言前四章學習筆記

第一章

第1節 進位計數制及其相互轉換

    使用一定個數的數碼的組合來表示數字,這種表示方法稱為進位計數制。根據所使用的數碼的個數,就產生了不同的進位計數制。

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

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


(1)減權定位法


(2)除基取餘法


將十進位制數除以基數2,其餘數為二進位制數的最低位,再用其商除2,其餘數為次低位,反覆做下去,直到商0


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


(1)減權定位法
(2)乘基取整法


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


(1)按權相加法
(2)逐次乘基相加法


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


(1)按權相加法
(2)逐次除基相加法


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


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


第2節 帶符號數的表示

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

一、原碼錶示

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

二、補碼的表示

1.補碼的定義

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

其中模數MI根據機器數的位數而定,如位數為8則N=28用補碼錶示的機器數,符號位仍然表示數的符號:0為正,1為負。對於正數,補碼與原碼相同,對於負數需要進行變換。

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

由於正數的原碼與補碼相同。

負數的真值變換為補碼的方法:將各位變反(0變1,1變0)然後在最低位加1.

負數的原碼變換為補碼:保持符號位不變,其餘各位變反,最低位加1。

3.補碼數的表示範圍

4.補碼的加減運算

規則:[X+Y]補=[X]補+[Y]補

[x-Y]補=[X]補-[Y]補=[X]補+[-Y]補

其中[-Y]補是對[Y]補執行一次求補運算

求補運算是將原數連同符號位一起(不管是正還是負)按位求反,再在最低位加1。


第3節 字元的表示

標準ASCII碼共有128個,可分為兩類:

非列印ASCII碼,共33個,用於控制操作,如BEL(響鈴07H),DEL(刪除7FH),CR(回車,0DH),LF(換行,0AH).

可列印ASCII碼共有95個,如數字符0~9,大小寫字母等。


第4節 基本邏輯運算

1.與運算
2.非運算
3.或運算
4.異或運算


第二章

第1節 IBM-PC微機基本結構

IBM-PC微機基本結構

運算器、控制器、儲存器、輸入裝置和輸出裝置。

將運算器和控制器兩大部件整合在一個積體電路晶片上,稱為中央處理器,簡稱CPU,也叫微處理器.

系統匯流排:地址匯流排、資料匯流排、控制匯流排

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

組合語言程式是由一系列的指令(指令序列)構成。

指令是構成組合語言程式的最基本單位,就象高階語言中的語句。

CPU執行指令序列就是重複執行以下兩個步驟:

從儲存器中取指令

執行指令規定的操作

這兩個步驟的執行又分為序列方式指令流水線方式。

1.序列方式

CPU -------取指|執行│存數│取指|執行|取指|取數|執行

系統匯流排----忙 |閒 |忙 |忙 |閒 |忙 |忙 |閒

特點:

(1)當CPU在指令執行階段,不需要佔用系統匯流排,但此時匯流排也不工作,因此係統匯流排的空閒時間比較多。

(2)在從儲存器取指令、取資料或存資料時,匯流排處於忙狀態,其所佔用的時間也較長。而CPU卻只需要花很短的時間去處理,因此大部分時間處於閒置狀態。

2.指令流水線方式

採用指令流水線工作方式的計算機具有較高的工作效率。CPU內部採用了一種先進的指令流水線結構,這種結構可以有效而充分地利用各主要硬體資源。

8086CPU結構: 執行單元EU 匯流排介面單元 BIU

(1)執行單元EU

EU的主要任務是分析與執行指令,具體包括:

A、從指令佇列中取出指令程式碼,由控制器譯碼後產生相應的控制訊號,控制各部件完成指令規定的操作。

B、對運算元執行各種指定的算術或邏輯運算。

C、向匯流排介面單元BIU傳送訪問主存或I/0的命令,並提供相應的地址和傳送的資料。

(2)匯流排介面單元BIU

BIU負責CPU與儲存器、IO的資訊傳送。具體包括:

A、取指令——根據CS暫存器和指令指標IP形成20位的實體地址,從相應的儲存器單元中取出指令,暫存到指令佇列中,等待EU取走並執行。

B、存取資料——在EU執行指令的過程中,需要與儲存器或I/O埠傳送資料時,由EU提供的資料和地址,結合段暫存器,通過外部匯流排與儲存器或I/O進行資料的存取。

執行過程:

BIU 取指1|取指2|取指3|存數|取指4|取數

EU 執行1|執行2|執行3|等待|執行4|

系統匯流排 忙 |忙 │忙 │忙 |忙 |忙


第2節 CPU暫存器結構及其用途

通用暫存器8個


AX AH|AL 累加器


BX BH|BL 基址暫存器


CX CH|CL 計數暫存器


DX DH|DL 資料暫存器


SP 堆疊暫存器


BP 基址指標


SI 源變址暫存器


DI 目的變址暫存器

段暫存器4個


IP 指令指標


FLAGS 標誌暫存器

段暫存器4個


CS 程式碼段暫存器


DS 資料段暫存器


ES 附加段暫存器


SS 堆疊段暫存器

一、通用暫存器


1.資料暫存器


它包括AX、BX、CX和DX四個暫存器。它們中的每一個既可以是16位暫存器,也可以分成兩個8位暫存器使用。即可以當作8個獨立的8位暫存器使用。


資料暫存器既可以用來存放參加運算的運算元,也可以存放運算的結果。在多數情況下,使用這些暫存器時必須在指令中明確指示。

2.指標暫存器

指標暫存器有堆疊指標SP和基址指標BP

它們一般被用來存放16位地址,在形成20位的實體地址時常被作為偏移量使用。

SP指標——在進行堆疊操作時,被隱含使用,被用來指向堆疊頂部單元。

BP指標——被用來指向堆疊段內某一儲存單元。BP除用作地址指標外也可以象資料暫存器一樣,存放參加運算的運算元和運算的結果。

3.變址暫存器

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

SI—源變址暫存器 DI——目的變址暫存器

同BP暫存器一樣,SI和DI也可以用作通用資料暫存器存放運算元和運算結果。

二、段暫存器

| CS--段基址--程式碼段
| DS--段基址--資料段
| SS--段基址--堆疊段
| ES--段基址--附加段

三、指令指標P

CPU在從儲存器取指令時,以段暫存器CS作為程式碼段的基址指標,以IP的內容作為偏移量,共同形成一條指令的存放地址。

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

注意:IP的內容不能被直接訪問,既不能用指令去讀IP的值,也不能用指令給它賦值。但是可以通過某些指令的執行而自動修改IP的內容。

例如,下面兩種指令就可以自動改變IP暫存器的內容。

轉移指令將指令中的目的地址的偏移量送入IP。

子程式呼叫指令CALL,將IP原有內容自動壓入堆疊,而將子程式的入口地址偏移量自動送入IP,而返回指令RET,又自動從堆疊中彈回原有IP的內容。

四、標誌暫存器

標誌暫存器是用來反映CPU在程式執行時的某些狀態,如是否有進位、奇偶性、結果的符號、結果是否為零等等。

8086/8088CPU中標誌暫存器的長度為16位,但只定義了其中的9位。

11--OF---溢位位


10--DF---方向位


9---IF---中斷允許位


8---TF---單步標誌位


7---SF---符號位


6---ZF---零值位


4---AF---輔助進位位


2---PF---奇偶位


0---CF---進位位

標誌位分為

狀態標誌:CF, PF,AF, ZF, SF, OF

控制標誌:TF,DF,IF

1.進位標誌位CF

在進行算術運算時,若最高位(對字操作是第15位,位元組操作是第7位勸產生進位或借位時CF被自動置“1”,否則置“0”

在移位類指令中,CF也被用來存放從最高位(左移時)或最低位(右移時)移出的數值(0或1)。

2.奇偶標誌位PF

當指令操作結果的低8位中含有1的個數為偶數時,則PF被置1,否則PF被置0。

注意:PF只反映操作結果的低8位的奇偶性,與指令運算元的長度無關。

3.輔助進位標誌位AF

在進行算術運算時,若低位元組的低四位向高4位產生進位或借位,即第3位產生進位或借位時,AF位被置1,否則置0。AF標誌位用於十進位制運算的調整。

注意:AF只反映運算結果低八位,與運算元長度無關。

4.零值標誌位ZF

若運算結果各位全為0,則ZF被置1,否則置0。

5.符號標誌位SF

將運算結果視為帶符號數,當運算結果為負數時SF被置1,為正數時,則置0。

由於第7位是位元組運算元的符號位,而第15位是字運算元的符號位,因此,SF位與運算結果的最高位(第7位或第15位)相同。

6.溢位標誌位OF

當運算結果超過機器用補碼所能表示數的範圍時,則OF置1,否則置0.

位元組資料,機器用補碼所能表示的數範圍為-128~~+127。字資料的表示範圍為:-32768~+32767

注意:溢位與進位是兩個完全不同的概念,不能相互混淆。下面通過幾個例子來說明

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

單步標誌也叫跟蹤位,該標誌為控制標誌位。單步標誌位供除錯程式使用。

當TF位被設定為1時,每執行一條指令後,CPU暫停執行,即產生單步中斷。

8.中斷允許標誌位IF

該標誌位為控制標誌位。當IF被設定為1時,CPU可以響應可遮蔽中斷,否則不允許響應可遮蔽中斷。

9.方向標誌位DF

DF也是控制標誌位。它被用來規定串操作指令的增減方向。

當DF=0時,串操作指令自動使變址暫存器(SI和DI)的內容遞增。當DF=1時,串操作指令自動使變址暫存器的內容遞減。


第3節 儲存器組織結構

一、儲存器的組成

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

儲存單元的多少就表示了儲存器的容量。

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

一個儲存單元的長度一般為8位二進位制數,即一個位元組。

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

8086/8088CPU有20根地址線,即它可以產生20位的地址碼,它的儲存器定址能力為220,)即1兆位元組空間。

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

一個字儲存單元(WORD)的長度為16位二進位制數,即兩個位元組。字單元的地址為兩個位元組單元中較小地址位元組單元的地址。

16位長資料的存放規則是低8位放在較低地址位元組單元中,高8位放在較高地址位元組單元中。

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

二、儲存器的段結構

由於8086/8088可定址的儲存空間為1MB,需要提供20位長的地址碼。而CPU內部的暫存器長度只有16位。能夠直接訪問的最大地址空間是64KB。

8086/8088系統的儲存器段結構具有以下幾個特點:

1.8086/8088CPU將1MB的儲存空間劃分成若干個段,每個段最大長度為64K (65536)個位元組單元組成。

⒉.每個段的基址(段基址)必須是一個小節的首址。

段基址——一個段的起始地址。

在儲存器中規定從0地址開始,每16個位元組單元稱為一個小節(Paragraph)。因此,1MB記憶體就可劃分為64K個小節。每個小節的首地址最低位必為0(16進位制數表示)因此段基址只能是上述64kK個小節首址之一。

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

邏輯段是指在組合語言源程式中設定的段

記憶體中的一個物理儲存單元可以映象到一個或多個邏輯段中

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

4個段分別是程式碼段、資料段、堆疊段和附加段,稱為當前段。4個段暫存器CS、DS、SS和ES分別儲存了它們段基址的高16位地址,稱為段基值。段基址的最低4位為0。(小節首址的低4位為全0)。

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

1.實體地址

在1MB的儲存空間中,每個儲存單元的實體地址是唯一的,它就是該儲存單元的20位地址。

2.邏輯地址

在程式設計中,為了便於程式的開發和對儲存器進行動態管理,使用了邏輯地址。

一個邏輯地址包括兩個部分(段基值和偏移量

段基值:存放在某一個段暫存器中,是一個邏輯段的起始單元地址((段基址)的高16位。

偏移量:表示某個儲存單元與它所在段的段基址之間的位元組距離。

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

當CPU要訪問儲存器時,需要由匯流排介面單元BIU將邏輯地址轉換成實體地址。

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

4.邏輯地址的來源

在程式的執行過程中,CPU根據不同操作型別訪問儲存器,其邏輯地址中段基值和偏移量的來源是不一樣的。下表是各種操作型別所對應的邏輯地址的來源。

(1)允許替代來源也叫做段超越,它表示了段基值除使用隱含的段暫存器外是否可以指定其它段暫存器來提供。(2)有效地址EA,它表示根據指令所採用的定址方式計算出來的段內偏移量。


第4節 堆疊及其操作方法

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

一、堆疊的構造

堆疊一般分為:專用堆疊儲存器和軟體堆疊

專用堆疊儲存器----按堆疊的工作方式專門設計的儲存器

軟體堆疊----由程式設計人員用軟體在記憶體中劃出的一塊儲存區作為堆疊來使用。8086/8088採用這種方式。

在堆疊中存取資料的規則是:“先進後出FILO”( First-In Last-Out)。即最先送入堆疊的資料要到最後才能取出,而最後送入堆疊的資料,最先取出。

在8086/8088微機中堆疊是由堆疊段暫存器SS指示的一段儲存區。

頂由堆疊指標SP指示。SP中內容始終表示堆疊段基址與棧項之間的距離(位元組數)。當SP內容為最大(初始)值時,表示堆疊為空。而當(SP) =0時,表示堆疊全滿.

當SP被初始化時,指向棧底+2單元,其值就是堆疊的長度。由於SP是16位暫存器,因此堆疊長度≤64K位元組。

資料在堆疊中的存放格式是:以字為單位存放,資料的低8位放在較低地址單元,高8位放在較高地址單元。

當用戶程式中要求的堆疊長度超過-一個堆疊段的最大長度64KB時,可以設定幾個堆疊段。

通過改變堆疊段暫存器SS的內容,即可改變到另一個堆疊段,當改變了堆疊段暫存器SS的內容後,必須緊接著賦予SP新值。

三、堆疊操作

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

當程式經過彙編、連線並裝入記憶體時,系統將自動為其分配一個儲存區作為堆疊段,將這個段的段基址的高16位送入SS中,將程式指定的位元組單元數100賦值給SP。

⒉.進棧PUSH

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

進棧的執行過程:

(1)首先將堆疊指標SP減2,即指向一個空的堆疊字單元

SP<=(SP)-2

(2)將要儲存的內容(暫存器或儲存單元的內容)送入SP指向的字單元中。(SP)<=資料

3.出棧POP

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

出棧的操作過程:

(1)將SP指向的字單元(即棧頂字單元)內容送往指定的暫存器或儲存器。

即:暫存器/儲存器<=((SP))

(2)堆疊指標SP內容加2,即:SP<= (SP) +2


第三章

第1節 定址方式

3.1定址方式

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

操作碼----運算元

操作碼:表示該指令應完成的具體操作,如加法、減法、乘法、移位等等。在組合語言中使用一定的符號來表示,稱為助記符。如ADD、PUSH、POP、MOV等等。

運算元:表示該指令的操作物件。如移位操作的被移位數,加法操作的加數等等。它可以是一個運算元,也可以是多個運算元。這取決於操作碼部分的具體需要。

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

Intel 8086/8088各指令中提供運算元的方法有以下四種:

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

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

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

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

1.立即數定址

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

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

源運算元:指在應用指令中,內容不隨指令執行而變化的運算元。

目的運算元:指在應用指令中,內容隨執行指令而改變的運算元。

MOV AL,BL;-----AL為目標運算元,BL為源運算元

⒉暫存器定址

暫存器定址方式是指指令中所需的運算元在CPU的某個暫存器中。暫存器可以是8位或16位通用暫存器,或者是段暫存器。如:AH、AL、AX、CX、DS、ES等。

例如: Mov(AX BX)

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

一個儲存單元邏輯地址表示形式:段基值:偏移量

段基值由某個段暫存器提供.

偏移量表示了該儲存單元與段起始地址之間的距離,也叫做有效地址EA。

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

⑴位移量:位移量是指令中直接給出的一個8位或16位數。一般源程式中以運算元名字(變數名或標號)的形式出現。

(2)基址:由基址暫存器BX或基址指標BP提供的內容。

(3)變址:由源變址暫存器SI或目的變址暫存器DI提供的內容

位移量、基址和變址三個地址分量組合時,若有兩個或兩個以上分量時,將進行以216為模的十六位加法運算。下面是由這三個地址分量的不同組合所形成的四種定址方式

3.直接定址

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

在組合語言源程式中,直接定址方式用符號或常數來表示。

(1)用符號表示

例:MOV BX,VAR=>MOV BX,DS:VAR

它表示將資料段中,偏移了VAR個位元組距離的字單元內容送到暫存器BX中。

MOV AL,DATA+2=>MOV AL, DS: DATA+2

它表示將資料段偏移了DATA+2的位元組單元內容送入AL中。

(2)用常數表示

例:MOV AX, DS: [64H]

它表示從當前資料段開始,偏移100個位元組的字單元內容送到AX中。不能寫為:MOV AX,64H

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

4.暫存器間接定址

運算元有效地址EA直接從基址暫存器(BX或P)或變址暫存器(SI或DI)中獲得。

暫存器間接定址就是事先將偏移量存放在某個暫存器(BX、BP、SI或DI)中,這些暫存器就如同一個地址指標。

在程式執行期間,只要對暫存器內容進行修改,就可以實現用同一條指令實現對不同儲存單元進行操作。

指示儲存器所在段的段奇仔器可以省略,當指令中使用的是BP暫存器,則隱含表示使用SS段暫存器,其餘情況則隱含使用DS段暫存器。

例如:

MOV Ax,[BX] =>MOV Ax, DS: [BX]

MOV BH,[BP] =>MOV BH, SS: [BP]

MOV [DI],BX =>MOV DS: [DI],BX

5.基址定址/變址定址

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

操作碼--定址特徵(BX/BP/SI/DI)--位移量

指令中使用BX或BP時為基址定址。指令中使用SI或DI時為變址定址。

段暫存器的隱含使用規則與暫存器間接定址方式相同

例:MOV AX,10H [SI]=>MOV AX, DS: 10H [SI]

注意:當位移量為常數時,不能加方括號。

這兩種定址方式只需通過改變暫存器的內容就可用一條指令訪問不同的儲存單元,並且由於增加了一個位移量分量,因此它們能夠很方便地訪問陣列和表格資料。

由於這兩種定址方式中暫存器中的內容是相對於由位移量指定的初始單元。因此也叫暫存器相對定址。

6.基址變址定址

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

EA=基址+變址+位移量

操作碼--定址特徵(BX/BP+SI/DI)--位移量

BX/BP+SI/DI+位移量=EA---->EA+段暫存器=運算元

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

例如:MOV CX, 100H [BX] [DI] (位移量 基址 變址)

MOV TABLE [BX] [DI], AX

下面的用法是錯誤的。

MoV AX,ARRAY [BX] [BP]

MOV AX,TABLE [SI] [DI]

在基址變址定址方式中,程式執行期間有兩個地址分量可以修改。因此它是最靈活的一種定址方式,可以方便地對二維陣列進行訪問。

7.串操作定址方式

8086/8088設定有專門用於串操作的指令,這些指令的運算元雖然也在儲存器中,但它們不使用前面介紹的各種定址方式,而隱含地使用變址暫存器SI和DI專門指示。

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

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

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

8.I/O埠定址

在計算機系統,對I/O埠的定址方式有以下兩種方法。

儲存器編址方法

將I/O埠視為儲存器的一個單元,對埠的訪問就如同訪問儲存單元一樣。訪問儲存器的指令和各種定址方式同樣適用對1/O埠的訪問。

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

I/O埠編址方法

I/O埠的地址與儲存器地址分開,並使用專門的輸入指令和輸出指令。

8086/8088系統中就是採用的這種方式。可以最多訪問64K個位元組埠或32K個字埠,用專門的IN指令和OUT指令訪問。定址方式有如下兩種。

(1)直接埠定址

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

直接埠定址可訪問的埠數為0~255個。

例如:IN AL, 25H

(2)暫存器間接揣口定址

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

例如:Mov Dx,378H

OUT DX,AL

如果訪問的埠地址值大於255,則必須用I/O埠的間址方式


第2節 指令系統

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)立即數傳送到通用暫存器或儲存單元

例:MOV AH,10H

注意:立即數只能作為源運算元,立即數不能傳送給段暫存器。

(2)暫存器之間的傳送

例:MOV AH,CH

MOV AX,CS;正確

MOV CS,AX;錯誤

注意:段暫存器CS只能作源運算元,不能作目的運算元。

(3)暫存器與儲存單元之間傳送

例:MOV AL, [SI]

MOV [DI],AH

MOV AX,10[BX]

MoV TABLE[BP], BX

MOV DS,[SI] [BX]

MOV [BX],[BP] [SI];錯誤

綜合起來,MOV指令在使用時需注意以下幾個問題:

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

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

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

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

⒉交換指令

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

指令對標誌暫存器各位無影響

資料交換可以在暫存器之間或暫存器與儲存器單元之間進行。但是不能在儲存單元之間直接進行資料交換。暫存器只能使用通用暫存器。

3.標誌傳送指令

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

(1)取標誌暫存器指令指令格式: LAHIF

作用:將標誌暫存器的低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)標誌出棧指令指令格式:POPF

作用:將由SP指向的堆疊頂部的一個字單元的內容送入標誌暫存器,然後SP的內容加2.

4.地址傳送指令

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

)裝入有效地址

格式:(LEA DEST,SRC

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

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

指令執行對標誌暫存器各位無影響。

例1:LEA AX,[BX] [SI]

源運算元使用的是基址變址定址方式,它所形成的有效地址就是BX的內容加上SI的內容。即

BX)+(SI

注意:它不是將BX和SI所定址的儲存單元的內容送入AX。

(2)裝入地址指標指令格式:LDS DEST, SRC

LES DEST,SRC

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

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

二、算術運算類指令

8086/8088指令系統中有加、減、乘、除指令,這些指令可以對位元組資料或字資料進行運算。

參加運算的數可以是無符號數,也可以是帶符號數。帶符號數用補碼錶示。

參加運算的數可以是二進位制數,也可以是十進位制數(以BCD碼錶示)。

1.加法指令

指令格式:ADD DEST,SRC

功能:目的運算元和源運算元相加,其和存放到目的運算元中,而源運算元內容保持不變,即

DEST<=(DEST)+(SRC)。

根據相加的結果將影響到標誌暫存器的CF、PF、AF、ZF、SF和OF。

DEST只能是通用暫存器或儲存器運算元。不能是立即數。

SRC可以是通用暫存器、儲存器或立即數運算元DEST和SRC不能都為儲存器運算元。

ADD指令可以是位元組運算元相加,也可以是字運算元相加。

例分析下列各指令功能(1) ADDAX,CX

功能:將暫存器AX的內容與CX的內容相加,結果傳送到AX中(2)ADD AH,DATA_BYTE

功能:將由直接定址方式所指示的儲存單元的內容與AH內容相

加,結果送回AH中。

(3)ADD CX,10H

功能:將常數10H加入到CX中。為字運算元指令.(4)ADD AX, [BX][SI]

⒉帶進位加法指令

指令格式:ADC DEST,SRC

該指令的功能與ADD基本相同,所不同的是其結果還要加上進位標誌CF的值,即:
DEST<=(DEST)+(SRC)+CF

根據相加的結果設定標誌暫存器中的CF、PF、AF、ZF、SF和OF

注意:參加運算的進位CF是本條指令執行之前的值。用ADC指令可實現資料長度大於16位的兩數相加

3.加1指令

指令格式:INC DEST

目的運算元可以是任意的8位、16位通用暫存器或儲存器運算元。目的運算元被視為帶符號二進位制數

根據指令執行結果設定PF、AF、ZF、SF和OF標誌,但不影響CF。INC指令主要用於某些計數器的計數和修改地址指標。

4.減法指令

指令格式:SUB DEST,SRC

功能:目的運算元的內容減去源運算元的內容,結果送入目的運算元,源運算元中內容保持不變。

即:DEST<=(DEST) - (SRC)

操作結果將影響標誌位CF、PF、AF、ZF、SF和OF。

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

注意:減法指令對借位標誌的影響,若採用變減為加的運算方法,則產生的進位與CF標誌結果相反。

5.帶借位減法

指令格式: SBB DEST,SRC

該指令的功能與SUB指令基本相同,不同的是在兩個運算元相減後再減去進位標誌CF的值。

即:DEST<=(DEST)—(SRC)一CF。注意:該CF的值是本條指令執行前的結果。

SBB指令在使用上與ADC類似,主要用於長度大於16位的數相減,即將低16位相減的結果引入高位部分的減法中。

根據指令執行結果設定PF、AF、ZF、SF、OF和CF。

6.減1指令

指令格式:DEC DEST

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

DEST可以是8位或16位的通用暫存器儲存器運算元,該指令將DEST看作是帶符號二進位制數。

根據指令執行結果設定PF、AF、ZF、SF和OF,但不影響CF。

DEC指令的使用類似INC指令。主要用於計數和修改地址指標,計數方向與INC指令相反。

7.求負數指令

指令格式:NEG DEST

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

DEST可以是任意一個8位或16位的通用暫存器或儲存器運算元,被視為帶符號的運算元。

由於機器中帶符號數用補碼錶示,求運算元的負數就是求補操作。因此,NEG指令也叫取補指令。NEG指令將影響標誌PF、AF、ZF、SF、CF和OF。

對進位標誌CF的影響:

只有當運算元為零時,進位標誌CF被置零,其它情況都被置1.

對溢位標誌OF的影響:

當位元組運算元為-128,或字運算元為-32768時,執行NEG指令的結果運算元將無變化,但溢位標誌OF被置1.

三、位操作類指令1.邏輯運算指令

邏輯運算指令共有4條,它們的指令格式分別是:

邏輯“與”指令AND DEST,SRC

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

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

邏輯指令對標誌位的影響:

NOT指令對標誌無影響。而其餘三條指令將根據結果影響SF、ZF和PF,而CF和OF總是置0,AF為不確定。

邏輯運算指令除用來實現各種邏輯運算之外,還常用於對位元組或字資料的某些位的組合、分離或位設定。

⒉測試指令

指令格式:TESTDEST SRC

該指令的功能與AND指令相似,實現源運算元與目的運算元進行按位“邏輯與”運算,對標誌位的影響與AND指令相同,但運算的結果不送入目的運算元,即目的運算元內容也將保持不變。TEST指令主要用於測試某一運算元的一位或幾位的狀態。

該程式段檢查AL暫存器的最低位是否為0,如果為0,則程式轉移到ZERO處執行。

該程式段檢查標誌暫存器的PF位(第2位)是否為0,如果為0,則執行後標誌ZF為1。因此通過測試ZF標誌即可。

3.移位/迴圈移位指令

這一類指令共有8條,分為3類。

(1)算術移位

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

(2)邏輯移位

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

邏輯左移SHL與算術左移SAL功能相同。

(3))迴圈移位小迴圈:

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

大迴圈:

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

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

(1)DEST為操作物件,它可以是位元組或字運算元,可以是通用暫存器或儲存器運算元。

(2) cOUNT用來決定移位/迴圈的位數,即確定移位的次數。

當移位次數為1時,使用常數1或暫存器CL)當移位次數大於1時,必須使用暫存器CL,

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

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

移位次數為1時,移位前後運算元的符號位發生變化,則OF被置1,否則置0。移位次數大於1時,OF不確定。

指令SAL和SAR當移位次為n時,其作用相當壬乘以2n或除以2",因此被叫做算術移位指令。

為了保持其算術運算結果的正確性,移位後的結果不能發生溢位。

對於多位元組或多字資料的移位,需要使用帶進位迴圈移位指令。

四、處理器控制類指令處理器控制類指令包括以下三種情況。1.標誌位操作指令

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

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

(2)置1進位標誌 ST9﹔置CF為1

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

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

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

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

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

2、與外部事件同步的指令HLT;暫停指令

WAIT;等待指令

ESC ;外部協處理器指令字首LOCK;匯流排鎖定指令

3、空操作指令NOP

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


第3節 指令編碼

3.3指令編碼

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

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

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

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

⒉單運算元指令編碼格式

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

4.其它指令編碼格式

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

對於象MOV、ADD、AND等雙運算元指令,運算元可以是以下兩種情形:

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

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

這類指令的機器目的碼長度為2~6個位元組

1.操作特徵部分

這部分為指令編碼的首位元組,它又分為以下三個段。(1)OPCODE:操作碼欄位

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

(2)方向欄位d

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

注意:當源運算元為立即數Imm時,d欄位無效,它被併入操作碼欄位。

(3)字/位元組欄位W

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

2.定址特徵部分

它與操作特徵部分的方向欄位d結合,指定兩個運算元分別使用什麼定址方式,及使用哪個暫存器。它包括MOD、REG和R/MS個欄位,REG欄位確定一個運算元,而MOD和R/M欄位確定另一個運算元。當d=1時,則目的運算元由REG欄位確定,而源運算元由MOD和R/M欄位確定。

(1) REG欄位

由REG欄位確定的一個運算元是某一通用暫存器的內容,即使用的是暫存器定址方式。

第一部分中的W欄位決定運算元是字或是位元組。

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

這兩個欄位共同確定一個運算元。該運算元可以在暫存器中,也可以在儲存器中

MOD、R/M和W欄位共同確定運算元的定址方式和所使用的暫存器,如下表所示。

3.位移量部分

根據定址特徵中MOD和R/M欄位確定的有效地址計算方法,位移量可以是以下三種情況之一:沒有位移量1位元組位移量disp8
2位元組位移量disp16

4.立即數部分

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

該指令為暫存器間址的儲存單元內容送通用暫存器AX指令中使用了段字首ES,即由ES代替資料段DS。指令編碼的第一個位元組就為段字首標記程式碼。

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

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

操作特徵部分:包括OPCODE)

和W三個欄位,其中V欄位只有移位/

迴圈指令中才有該欄位。其它指令中沒有該欄位。

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

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

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

這種編碼格式用於隱含指定AX/AL作為一個運算元的雙運算元指令,其編碼格式為:

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

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

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

四、其它指令編碼格式

除上述三種編碼格式外,還有一些指令的編碼格式更簡單。如標誌位操作指令、堆疊操作指令等。這些指令的編碼格式一般只有一個位元組。

在有些單位元組指令的編碼中,將該位元組劃出部分位作為REG欄位。例如PUSH指令,若壓入堆疊的是通用暫存器,則編碼格式為:
7
3 2 10
oPCODE REG01010
若壓棧的是段暫存器則編碼格式為:

第四章

第1節 組合語言語句種類及其格式

4.1組合語言語句種類及其格式
中l
組合語言的語句可以分為指令語句和偽指令語句
一、指令語句
每一條指令語句在彙編時都要產生一個可供CPU執行的機器目的碼,它又叫可執行語句。
指令語句的一般格式為:
標號
指令助記符
運算元
註釋

標號
指令助記符運算元
註釋
1.標號欄位
標號是可選欄位,它後面必須有“:”。標號是一條指令的符號地址,代表了該指令的第一個位元組存放地址。
標號一般放在一個程式段或子程式的入口處,控制程式的執行轉到該程式位置。
在轉移指令或子程式呼叫指令中,可直接引用這個標號。

2.指令助記符欄位
該欄位是一條指令的必選項,它表示這條語句要求CPU完成什麼具體操作,如MOV、ADD, SHL等。
有些指令還可以在指令助記符的前面加上字首,實現一定的附加操作。如串操作指令前所加的重複字首REP(見第7章介紹)等。

3.運算元欄位
一條指令可以有一個運算元、兩個運算元或者無運算元。
如ADD、 MOV指令需要兩個運算元,INC NOT指令只需一個運算元,而CLC指令不需要運算元。

4.註釋欄位
註釋欄位為可選項,該欄位以分號;開始。它的作用是為閱讀程式的人加上一些說明性內容註釋欄位不會產生機器目的碼,它不會影響程式和指令的功能。
註釋欄位可以是一條指令的後面部分,也可以是整個語句行。

二、偽指令語句
偽指令語句又叫命令語句。
偽指令本身並不產生對應的機器目的碼。它僅僅是告訴彙編程式對其後面的指令語句和偽指令語句的運算元應該如何處理。
一條偽指令語句可以包含四個欄位。如下所示:

一符號名
偽指令符
運算元
註釋
1.符號名欄位
該欄位為可選項。根據偽指令的不同,符號名可以是常量名、變數名、過程名、結構名和記錄名等等。
一條偽指令語句的符號名可以作其它偽指令語句或指令語句的運算元,這時它表示一個常量或儲存器地址
注意:符號名後面沒有冒號: ,這是與指令語句的重要區別。

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

3.運算元欄位
該欄位是否需要,以及需要幾個是由偽指令符欄位來決定。
運算元可以是一個常數(二進位制、十進位制、十六進位制等)、字串、常量名、變數名、標號和一些專用符號(如BYTE, FAR PARA等)。

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

三、識別符號
指令語句中的標號和偽指令語句中符號名統稱為識別符號。識別符號是由若干個字元構成的。識別符號構成規則:
1.字元的個數為1~31個;
2第一個字元必須是字母、問號、@或下劃線“_”這4種字元之一;
3.從第二個字元開始,可以是字母、數字)
_”或問號“?”;
4.不能使用屬於系統專用的保留字。


第2節 組合語言資料

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

一、常數
常數在彙編期間其值已完全確定,並且在程式執行過程中,其值不會發生變化。
常數有以下幾種形式:
1.二進位制數:以字母B結尾,如01001001B2八進位制數:以字母O或Q結尾,如631Q 25403.十進位制數:以字母D結尾,或者沒有結尾字母。如2007D、2007。

4.十六進位制數:以字母H結尾,如3FEH,如果常數的第一個數字為字母,為了與識別符號加以區別,必須在其前面冠以數字“0”。
5.實數。一般格式為:
±整數部分·小數部分E±指數部分
尾數
例2.134E+10
彙編程式在彙編源程式時,可以把實數轉換為4位元組、8位元組或10位元組的二進位制數形式存放。

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

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

(1)作指令語句的源運算元
MOVAX,QB2FOHADDAH,64H

(2)在指令語句的直接定址方式變址(基址)定址方式或基址變址定址方式中作位移量。
MOV BX,(32H sr
MOV 0ABH [BX,cxADC DX,1234H)BP]DI]

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

二、變數

變數用來表示存放資料的儲存單元,這些資料在程式執行期間可以被改變。
程式中以變數名的形式來訪問變數,因此,可以認為變數名就是存放資料的儲存單元地址。
1.變數的定義與預置
定義變數就是給變數在記憶體中分配一定的儲存單元。也就是給這個儲存單元賦與一個符號名,即變數名,同時還要將這些儲存單元預置初值。
定義變數使用資料定義偽指令DB、DW、DD、DQ和DT等。

當變數被定義後,就具有了以下三個屬性:(1)段屬性
它表示變數存放在哪一個邏輯段中。
例如上面例子中的變數DATA1、DATA2和DATA3三個變數都存放在VAR-DATA邏輯段中。
(2)偏移量屬性(OFFSET)
它表示變數所在位置與段起始點之間的位元組數。
如上述例子中,變數DATA1的偏移量為0,DATA2為1,DATA3為3。

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

(3)型別屬性
它表示變數佔用儲存單元的位元組數。其中DB偽指令定義的變數為位元組,DW定義的變數為字,DD定義的為雙字(4位元組),DQ定義的為4字,DT定義的為5字。
在變數的定義語句中,給變數賦初值的表示式可以使用下面4種形式:
(1)數值表示式
例如:( DATA1)DB32,|30H
DATA1的內容為32(2oH) , DATA1+1單元內容為30H.

(2)?表示式
不帶引號的問號“?”表示可以預置任意內容。例如:(DA-BYTEDB,,[?
表示讓彙編程式分配三個位元組儲存單元。這些儲存單元的內容的值為任意值。
(3)字串表示式
對於DB偽指令,字串為用引號括起來的不超過255個字元。給每一個字元分配一個位元組單元。字串按從左到右,將字元的ASCII編碼值以地址遞增的排列順序依次存放。

對於DD偽指令,只能給兩個序符組成的字串分配4個位元組單元。
兩個字元存放在較低地址的兩個位元組單元中。存放順序與DW偽指令相同,而較高地址的兩個位元組單元存放0.

注意:DW和DD偽指令不能用兩個以上字元構成的字串賦初值,否則將出錯。

含中畫
(4)DUP表示式
DUP稱為重複資料操作符。
使用DUP表示式的一般格式為:
變數名
DW
表示式1DUP(表示式2)
DD

⒉變數的使用
(1)在指令語句中引用
在指令語句中直接引用變數名就是對其儲存單元的內容進行存取
例如:DA1 DB OFEH
DA2 DW 52ACH
MOV AL,DA1;將0FEH傳送到AL中MOV BX,DA2 ;將52ACH傳送到BX中

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

取變數段基值和偏
後面三條偽指令的運算元中都
移量。前兩個位元組
包含了前面定義的兩個變數
存偏移量)後兩個位元組存段基值
設上述語句所在段的段基值為0915H,
NUM的偏移量為0004H,則儲存單元的分配情況如圖所示。

它表示取變數地址的偏移量

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

每個標號具有三屬性(1)段屬性(SEG)
它表示該標號所代表的地址在哪個邏輯段中,即段基值。(2)偏移量屬性(OFFSET)
它表示該標號所代表的地址在段內與段起點間的位元組數,即地址的偏移量。
(3)距離屬性(也叫型別屬性)
它表示該標號可以被段內還是段間的指令呼叫。NEAR(近)
該標號只能作段內轉移,也就是說只能
是與該標號所指指令同在一個邏輯段的轉移指令和呼叫指令才能使用它。

FAR(遠):該標號可以被非本段的轉移和呼叫指令使用。標號的距離屬性可以有兩種方法來指定:
a.隱含方式
當標號加在指令語句前面時,它隱含為NEAR屬性。例SUB1: MOV AX,30H
SUB1的距離屬性為NEAR也就是它只能被本段的轉移指令和呼叫指令訪問。
b.用LABEI)偽指令給標號指定距離屬性格式:標號名LABEL型別
型別為NEAR或FAR。該語句應與指令語句連用。

SUB1_FAR與SUB1兩個標號具有相同的段屬性和偏移量屬性,即相同的邏輯地址。被轉移指令或呼叫指令訪問時,是指同一個入口地址,但SUB1-FAR可以被其它段的指令呼叫。
LABEL偽指令還可以用來定義變數的屬性,即改變一個變數的屬性,如把字變數的高低位元組作為位元組變數來處理。


第3節 符號定義語句

4.3符號定義語句
在源程式設計中,使用符號定義語句可以將常數或表示式等內容用某個指定的符號來表示。在8086/8088組合語言中有兩種符號定義語句。
一、等值語句
語句格式:符號名 EQU表示式
功能:用符號名來表示EQU右邊的表示式。後面的程式中一旦出現該符號名,彙編程式將把它替換成該表示式。表示式可以是任何形式,常見的有以下幾種情況。1.常數或數值表示式


⒉地址表示式
ADR1 EQU DS:[BP+14]
ADR1被定義為在DS資料段中以BP作基址定址的一個儲存單元。
3.變數、暫存器名或指令助記符
例如:CREG EQU CX;在後面的程式使用CREG就是使用CX
CBD EQU DAA;DAA為十進位制調整指令。
注意:在同一源程式中,同一符號不能用EQU定義多次。
例:CBD EQU DAA
CBD EQU ADD錯誤用法

二、等號語句
格式:符號名=表示式
等號語句與等值語句具有相同的作用。但等號語句可以對一個符號進行多次定義。

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


第4節 表示式與運算子

4.4表示式與運算子
表示式是指令或偽指令語句運算元的常見形式。它由常數、變數、標號等通過操作運算子連線而成。
注意:任何表示式的值在程式被彙編的過程中進行計算確定,而不是到程式執行時才計算。
8086/8088巨集組合語言中的操作運算子非常豐富,可以分為以下五類。
一、算術運算子
+、——、*、l、MOD、SHL、SHR、[]
1.運算子“+”和“”也可作單目運算子,表示數的正負。

2.使用“+"、“_”、“*”、和“/"運算子時,參加運算的數和運算結果都是整數。
3.“/P運算為取商的整數部分,而“MOD”運算取除法運算的餘數。

4."SHR”和“SHL”為邏輯移位運算子iSHR為右移,左邊移出來的空位用0補入。"SHL為左移,右邊移出來的空位用0補入。
注意:移位運算子與移位指令區別。移位運算子的操作物件是某一具體的數(常數),在彙編時完成移位操作。而移位指令是對一個暫存器或儲存單元內容在程式執行時執行移位操作。

5.下標運算子“[]”具有相加的作用一般使用格式:表示式1[表示式2]
作用:將表示式1與表示式2的值相加後形成一個儲存器運算元的地址。

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

三、關係運算符
關係運算符包括:EQ(等於)、NE(不等於)、LT(小於)、LE(小於等於)、GT(大於)、GE(大於等於)

關係運算符用來比較兩個表示式的大小。關係運算符比較的兩個表示式必須同為常數或同一邏輯段中的變數。
如果是常量的比較,則按無符號數進行比較;如果是變數的比較,則比較它們的偏移量的大小。
關係運算的結果只能是“真”(全1)或“假”(全0)

四、數值返回運算子
該類運算子有5個,它們將變數或標號的某些特徵值或儲存單元地址的一部分提取出來。
1.SEG運算子
作用:取變數或標號所在段的段基值。

2.OFFSET運算子
該運算子的作用是取變數或標號在段內的偏移量。

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

4.LENGTH運算子
該運算子用於取變數的長度。
如果變數是用重複資料操作符DUP說明的,則LENGTH運算取外層DUP給定的值。
如果沒有用DUP說明,則LENGTH運算返回值總是1。

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連用,用來定義一個變數或標號的型別屬性。所定義的變數或標號的段基值和偏移量與緊跟其後的變數或標號相同。

六、運算子的優先順序
在一個表示式中如果存在多個運算子時,在計算時就有先後順序問題。不同的運算子具有不同的運算優先級別。

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

先執行優先級別高的運算,再算較低級別運算;>相同優先級別的操作,按照在表示式中的順序,從左到右進行;
可以用圓括號改變運算的順序。


第5節 程式的段結構

4.5程式的段結構
8086/8088在管理記憶體時,按照邏輯段進行劃分,不同的邏輯段可以用來存放不同目的的資料。在程式中使用四個段暫存器CS,DS,ES和SS來訪問它們。
在源程式設計時,使用偽指令來定義和使用這些邏輯段。

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

段定義偽指令語句各部分的作用如下:1、段名
段名是由使用者自己任意選定的,符合識別符號定義規則的一個名稱。
最好選用與該邏輯段用途相關的名稱。如第一個資料段為DATA1,第二個資料為DATA2等。
一個段的開始與結尾用的段名必須一致。

2、定位型別
定位型別用於決定段的起始邊界,即第一個可存放資料的位置(不是段基址)。它可以有4種取值。
(1)PAGE:表示該段從一個頁面的邊界開始
由於一個頁面為256個位元組,並且頁面編號從0開始,因此,PAGE定位型別的段起始地址的最後8位二進位制數一定為0,即以00H結尾的地址。
(2)PARA:表示該段從一個小節的邊界開始如果使用者未選定位型別,則預設為PARA。

(3) WORD:表示該段從一個偶數字節地址開始,即段起始單元地址的最後一位二進位制數一定是0。
(4)BYTE:表示該段起始單元地址可以是任一地址值。
注意:定位型別為PAGE和PARA時,段起始地址與段基址相同。定位型別為WORD和BYTE時,段起始地址與段基址可能不同。

3、組合型別
3、組合型別

組合型別說明符用來指定段與段之間的連線關係和定位。它有六種取值選擇。
組合型別說明符用來指定段與段之間的連線關係和定位.它有六種取值選擇.

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

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

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

(4)STACK:把所有同名段連線成一個連續段,且系統自動對SS段暫存器初始化為該連續段的段基址。並初始化堆疊指標SP。
使用者程式中應至少有一個段用STACK說明,否則需要使用者程式自己初始化SS和SP。
(5)AT表示式:表示本段可定位在表示式所指示的小節邊界上。表示式的值也就是段基值。
(6)MEMORY:表示本段在儲存器中應定位在所有其它段之後的最高地址上。如果有多個用MEMORY說明的段,則只處理第一個用MEMORY說明的段。其餘的被視為COMMON

4.類別名
t
類別名為某一個段或幾個相同型別段設定的型別名稱。系統在進行連線處理時,把類別名相同的段存放在相鄰的儲存區,但段的劃分與使用仍按原來的設定。
類別名必須用單引號引起來。所用字串可任意選定,但它不能使用程式中的標號、變數名或其它定義的符號。
在定義一個段時,段名是必須有的項,而定位型別、組合型別和類別名三個引數是可選項。各個引數之間用空格分隔。各引數之間的順序不能改變。

二、段定址偽指令
段定址偽指令ASSUME的作用是告訴彙編程式,在處理源程式時,定義的段與哪個暫存器關聯。
ASSUME並不設定各個段暫存器的具體內容,段暫存器的值是在程式執行時設定的。
一般格式:
ASSUME段暫存器名:段名,段暫存器名:段名
其中段暫存器名為CS,DS,ES和SS四個之一,段名是用SEGMENT/ENDS偽指令定義的段名。

在一個程式碼段中可以有幾條ASSUME偽指令,對於前面的設定,可以用ASSUME改變原來的設定。
一條ASSUME語句不一定設定全部段暫存器,可以選擇其中一個或幾個段暫存器。
可以使用關鍵字NOTHINC將前面的設定刪除。

三、段暫存器的裝入
段暫存器的初值(段基值)裝入需要用程式的方法來實現。四個段暫存器的裝入方法略有不同。
1、DS和ES的裝入
在程式中,使用資料傳送語句來實現對DS和ES的裝入。

為了改正上述程式中的錯誤,可以在變數DBYTE2前加一個段字首說明即可。即:
MOV(ES:pBYTE2[2],AL
2、SS的裝入
SS的裝入有兩種方法
(1)在段定義偽指令的組合型別項中,使用STACK引數,並在段定址偽指令ASSUME語句中把該段與SS段暫存器關聯。

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

3、CS的裝入
中E
CPU在執行指令之前根據CS和IP的內容來從記憶體中提取指令,即必須在程式執行之前裝入CS和IP的值。因此,CS和IP的初始值就不能用可執行語句來裝入。
裝入CS和IP一般有下面兩種情況。
(⑴由系統軟體按照結束偽指令指定的地址裝入初始的CS和IP任何一個源程式都必須以END偽指令來結束。
其格式為:END起始地址
起始地址可以是一個標號或表示式,它與程式中第一條指令語句前所加的標號必須一致。

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


第6節 過程定義偽指令

4.6過程定義偽指令(PROC/ENDP)
在程式設計過程中,常常將具有一定功能的程式段設計成一個子程式。在MASM巨集彙編程式中,用過程(PROCEDURE)來構造子程式。

過程名是子程式的名稱,它被用作過程呼叫指令CALL的目的運算元。它類同一個標號的作用。具有段、偏移量和距離三個屬性。而距離屬性使用NEAR和FAR來指定,若沒有指定,則隱含為NEAR。
NEAR過程只能被本段指令呼叫,而FAR過程可以供其它段的指令呼叫。
每一個過程中必須包含有返回指令RET,其作用是控制CPU從子程式中返回到呼叫該過程的主程式。


第7節 當前位置計數器與定位偽指令

4.7當前位置計數器$與定位偽指令ORG(Origin)
彙編程式在彙編源程式時,每遇到一個邏輯段,就要為其設定一個位置計數器,它用來記錄該邏輯段中定義的每一個數據或每一條指令在邏輯段中的相對位置。
在源程式中,使用符號S來表示位置計數器的當前值。因此,S被稱為當前計數器。它位於不同的位置具有不同的值。
位置計數器S在使用上完全類似變數的使用.


第8節 標題偽指令TITLE

4.8標題偽指令TITLE
語句格式:
TITLE標題名
作用:給所在程式指定一個標題。以便在列表檔案的每一頁的第一行都顯示這個標題。其中標題是使用者任意選用的字串,字元個數不能超過60。


第9節 從程式返回作業系統的方法

4.9從程式返回作業系統的方法
為了使程式執行結束後,能夠正確地返回到作業系統,需要在程式中加上一些必要的語句。一般有以下兩種方法。

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

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

1.將使用者程式編製成一個過程,型別為FAR;
2.將PSP的起始邏輯地址壓棧,即將INT20HI指令的地址壓棧;3.在使用者程式結尾處,使用一條RET指令。執行該指令將使儲存在堆疊中的PSP的起始地址彈出到CS和IP中。

二、使用DOS系統功能呼叫實現返回
執行DOS功能呼叫4CH,也可以控制使用者程式結束,並返回DOS作業系統。
在程式結束時,使用兩條指令:
MOV AH,4CHINT 21H