20192417張家華 組合語言前四章筆記
第一章 基礎知識
1.1 組合語言的一般概念
機器語言:把控制計算機的命令和各種資料直接用二進位制數碼錶示的程式設計語言
高階語言:將計算機內部的操作細節遮蔽起來
組合語言:使用字母和符號來表示機器語言的命令,用十進位制數或十六進位制數來表示資料
2.進位計數制及其相互轉換
B 二進位制數
O或Q 八進位制數
D 十進位制數
H 十六進位制數
3.帶符號數的表示
真值:用“+”或“-”表示正負的數
機器數:用0或1表示正負的數
原碼:最高位用0/1表示,0有兩種表示形式 補碼:正數補碼與原碼相同,負數原碼符號位不變,各位取反最低位加1,0的八位補碼只有一個 【X-Y】補=【X】補+【-Y】補,求補:連同符號位按位取反,最低位加1
4.字元的表示
ASCII碼:一位元組,最高位表示奇偶校驗位,低七位表示字元編碼;共128個,非列印33個
5.基本邏輯運算
與 或 非 異或
第二章 微機結構
1. IBM-PC微機基本結構
基本結構:
中央處理器:CPU,微處理器,包括運算器和控制器
主儲存器:存放程式和資料,由若干個儲存單元構成
將CPU與主儲存器合稱為主機
I/O裝置與介面
系統匯流排:包括地址匯流排、資料匯流排和控制匯流排
功能結構:
CPU執行指令:
1.從儲存器中取指令
2.執行指令規定的操作
序列方式:計算機執行速度慢
指令流水線方式:劃分為執行單元和匯流排介面單元
2.CPU暫存器結構及其用途
1.通用暫存器:
資料暫存器:包括AX、BX、CX、DX四個暫存器;存放運算元或運算結果 隱含使用:在某些指令中,不需要明確指出使用的暫存器名,即隱含使用對應暫存器,例如在迴圈指令LOOP中,CX被隱含 指定作迴圈次數計數用; 特定使用:必須在指令中指明它的名字,例如移位指令SHL AX,CL, CL被固定用作移位次數。 指標暫存器:有堆疊指標SP和基址指標BP SP指標——在進行堆疊操作時被隱含使用,用來指向堆疊頂部單元 BP指標——被用來指向堆疊段內某一儲存單元 變址暫存器:有兩個16位的變址暫存器SI(源變址暫存器)和DI(目的變址暫存器),一般被用來作地址指標
2.段暫存器:每個儲存段用一個段暫存器來指明該段的起始位置(也叫段基址)
CPU訪問儲存單元需指明:段基址、偏移量
3.指令指標IP
CPU從儲存器取指令時,以段暫存器CS作為程式碼段的基址指標,以IP的內容作為偏移量,共同形成一條指令的存放地址
當CPU從記憶體中取出一條指令後,IP內容自動修改為指向下一條指令
4.標誌暫存器
用來反映CPU在程式執行時的某些狀態,如是否有進位、奇偶性、結果的符號、結果是否為零
長度為16位但只定義9位
進位標誌位CF:在算術運算時,若最高位(字操作的第15位,位元組操作的第7位)產生進位或借位時CF被自動置“1”;在移 位指令中,CF用來存放左移最高位或右移最低位移出的數值
奇偶標誌位PF:當指令操作結果的低8位中含有1的個數為偶數時,PF置1,否則置0
輔助進位標誌位AF:在算數運算時,若低位元組的低四位向高四位產生進位或借位,AF置1,否則置0
零值標誌位ZF:結果各位全為0,則ZF置1,否則置0
符號標誌位SF:運算結果為負數時置1,為正數時置0
溢位標誌位OF:當運算結果超過機器用補碼所能表示數的範圍時,OF置1,否則置0
對於位元組資料,機器用補碼所能表示數的範圍為-128 ~ +127
對於字資料,機器用補碼所能表示數的範圍為-32768 ~ +32767
單步標誌位TF:也叫跟蹤位,供除錯程式使用
中斷允許標誌位IF:IF為1,CPU可以響應可遮蔽中斷,否則不允許響應可遮蔽中斷
方向標誌位DF:用來規定串操作指令的增減方向。DF=0時,串操作指令自動使變址暫存器(SI和DI)的值遞增;DF=1 時,串操作指令自動使變址暫存器的值遞減
3.儲存器組織結構
1.儲存器的組成
任何兩個相鄰的位元組單元構成一個字單元(WORD),地址為較小地址位元組單元的地址。
在儲存器中規定從0地址開始,每16個位元組單元稱為一個小節(paragraph),每個段的基址必須是一個小節的首地址。1MB記憶體可劃分為64K個小節。
2.邏輯地址與實體地址及對應關係
實體地址:在1MB的儲存空間中,每個儲存單元的實體地址是唯一的(20位地址)。
邏輯地址:包含段基值(段基址的高16位)和偏移量兩個部分
邏輯地址轉換為實體地址:將邏輯地址的端基值左移4位,形成20位的段基址(低4位為0)然後與 16位的偏移量相加,結果即為20位的實體地址
4.堆疊及其操作方法
堆疊用途:主要用於暫存資料以及在過程呼叫或處理中斷時儲存斷點資訊
一般分為:專用堆疊儲存器和軟體堆疊
堆疊操作
1.設定堆疊:主要是對堆疊段暫存器SS和堆疊指標SP賦值
2.進棧PUSH
(1)將堆疊指標SP-2,即指向一個空的堆疊字單元
(2)將要儲存的內容送入SP指向的字單元中
3.出棧POP
(1)將SP指向的字單元內容送往指定的暫存器或儲存器
(2)將堆疊指標SP內容+2
第三章 定址方式與指令系統
1.定址方式
一條指令由操作碼和運算元兩部分組成
Intel 8086/8088各指令中提供運算元的方法有四種:
立即數運算元: 運算元在指令程式碼中提供,可以是8位,也可以是16位
暫存器運算元: 運算元在CPU的通用暫存器或段暫存器中
儲存器運算元: 運算元在記憶體的儲存單元中
I/O埠運算元:運算元在輸入/輸出介面的暫存器中
1.立即數定址
2.暫存器定址
下面四種定址方式是由三個地址分量的不同組合所形成的(1123)
3.直接定址:運算元的有效地址EA只有位移量地址分量
4.暫存器間接定址:運算元有效地址EA直接從基址暫存器(BX或BP)或變址暫存器(SI或DI)中 獲得
在程式執行期間,只要對暫存器內容進行修改,就可以實現用同一條指令實現對不同儲存單元進行操作。
5.基址定址/變址定址:運算元的有效地址EA等於基址分量或變址分量加上指令中給出的位移量
6.基址變址定址:運算元的有效地址是三個地址分量之和,即:EA = 基址+變址+位移量
7.串操作定址方式
在尋找源運算元時,隱含使用SI作為地址指標。
在尋找目的串時,隱含使用DI作為地址指標。
在串操作完成之後,自動對SI和DI進行修改,使它們指向下一個運算元。
8.I/O埠定址
儲存器編址方法:將I/O埠視為儲存器的一個單元,對埠的訪問就如同訪問儲存單元一樣。訪問儲存器的指令和各種定址方式同樣適用對I/O埠的訪問。
I/O埠編址方法:I/O埠的地址與儲存器地址分開,並使用專門的輸入指令和輸出指令。
直接埠定址:在指令中直接給出埠地址,埠地址一般採用2位十六進位制數,也可以用符號表示。直接 埠定址可訪問的埠數為0~255個
暫存器間接埠定址:把I/O埠的地址先送到DX中,用DX作間接定址暫存器;如果訪問的埠地址值大 於255,則必須用I/O埠的間接定址方式
2.指令系統
從指令的格式劃分,一般可以分為三種:
-
雙運算元指令:OPR DEST SRC
-
單運算元指令:OPR DEST
-
無運算元指令:OPR
對於無運算元指令,包含兩種情況:
1.指令不需要運算元,如暫停指令HLT 2.在指令格式中,沒有顯式地指明運算元,但是它隱含指明瞭運算元的存放地方,如指令PUSHF
從指令作用劃分,可以分為六大類:
1.傳送類指令:將資料資訊或地址資訊傳送到一個暫存器或儲存單元中,分為以下四種情況:
(1)通用資料傳送指令:格式:MOV DEST,SRC,將源運算元指定的內容傳送到目的運算元
三種情況:
立即數傳送到通用暫存器或儲存單元
暫存器之間的傳送
暫存器與儲存單元之間傳送
(2)交換指令:格式:XCHG DEST,SRC,將源運算元和目的運算元兩者內容相互交換
可以在暫存器之間或暫存器與儲存器單元之間進行,但是不能在儲存單元之間直接進行資料交換,應當使用 一個暫存器通過兩次暫存器與儲存單元之間的交換完成。
(3)標誌傳送指令:對標誌暫存器進行存取
有4條,都是無運算元指令,即指令隱含指定標誌暫存器、AH暫存器或堆疊為運算元
取標誌暫存器指令,格式:LAHF
功能:將標誌暫存器的低8位送入AH暫存器,即將標誌 SF、ZF、AF、PF和CF分別送入AH的第7、6、4、2、0 位, 而AH的第5、3、1位不確定。指令執行對標誌暫存器各位無影響
儲存標誌暫存器指令,格式:SAHF
功能:將暫存器AH中的第7、6、4、2、0位分別送入標誌寄 存器的SF、ZF、AF、PF和CF各標誌位。而標誌暫存器高 8 位中的各標誌位不受影響
標誌進棧指令,格式:PUSHF
功能:先將堆疊指標SP減2,使其指向堆疊頂部的空字單元,然後將16位標誌暫存器的內容送SP指向的字單元
標誌出棧指令,指令格式:POPF
功能:將由SP指向的堆疊頂部的一個字單元的內容送 入標誌暫存器,然後SP的內容加2
(4)地址傳送指令:將儲存單元的地址送暫存器
裝入有效地址,格式:LEA DEST,SRC,源運算元SRC必須是一個位元組或字儲存器運算元 (地址),DEST必須是一個16 位通用暫存器。
功能:將SRC儲存單元地址中的偏移量,即有效地址EA傳送到一個16位通用暫存器中。指令執行對標誌寄 存器各位無影響
裝入地址指標指令,格式:LDS DEST,SRC; LES DEST,SRC。DEST是任意一個16位通用暫存器。SRC必須是一個 儲存器運算元。
功能:把SRC儲存單元開始的4個位元組單元的內容(32位地址指標)送入DEST通用暫存器和段暫存器 DS(LDS指令)或ES(LES指令),其中低字單 元內容為偏移量送通用暫存器,高字單元內容 為段基值送DS或ES
2.算術運算類指令
加法指令,格式:ADD DEST,SRC。
帶進位加法指令,格式:ADC DEST,SRC,功能與ADD基本相同,所不同的是其結果還要加上進位標誌CF的值
加1指令,格式:INC DEST
減法指令,格式:SUB DEST,SRC
帶借位減法,格式:SBB DEST,SRC
減1指令,格式:DEC DEST
求負數指令,格式:NEG DEST
對進位標誌CF的影響:只有當運算元為零時,進位標誌CF被置零,其它情況都被置1
對溢位標誌OF的影響:當位元組運算元為-128,或字運算元為-32768時,執行NEG指令的結果運算元將無變化,但溢位 標誌OF被置1
由於機器中帶符號數用補碼錶示,求運算元的負數就是求補操作。因此NEG指令也叫取補指令
3.位操作類指令
(1)邏輯運算指令
邏輯“與”指令 AND DEST, SRC
邏輯“或”指令 OR DEST, SRC
邏輯“異或”指令 XOR DEST, SRC
邏輯“非”指令 NOT DEST
(2)測試指令,格式:TEST DEST, SRC,主要用於測試某一運算元的一位或幾位的狀態
功能與AND指令相似,對標誌位的影響與AND指令相同,但運算的結果不送入目的運算元。
(3)移位/迴圈移位指令,8條3類:
算術移位
算術左移 SAL DEST,COUNT
算術右移 SAR DEST,COUNT
邏輯移位
邏輯左移 SHL DEST,COUNT
邏輯右移 SHR DEST,COUNT
迴圈移位
小迴圈
迴圈左移 ROL DEST,COUNT
迴圈右移 ROR DEST,COUNT
大迴圈
帶進位迴圈左移 RCL DEST,COUNT
帶進位迴圈右移 RCR DEST,COUNT
4.處理器控制類指令
標誌位操作指令:
清除進位標誌CLC:置CF為0
置1進位標誌STC:置CF為1
進位標誌取反CMC:CF的值取反
清除方向標誌CLD:置DF為0
置1方向標誌STD:置DF為1
清除中斷標誌CLI:置IF為0
置1中斷標誌STI:置IF為1
與外部事件同步的指令
HLT:暫停指令
WAIT:等待指令
ESC:外部協處理器指令字首
LOCK:匯流排鎖定指令
空操作指令NOP:執行一次NOP佔用CPU三個時鐘週期,不改變任何暫存器或儲存單元內容
5.串操作類指令
6.程式轉移類指令
3.指令編碼
四種編碼格式:
1.雙運算元指令編碼格式:
2~6個位元組,可以包含4個部分,但其中某些部分在一些指令的編碼中可以沒有:
操作特徵部分:OPCODE操作碼欄位+方向欄位d+字/位元組欄位W
定址特徵部分:MOD+REG+R/M
位移量部分:根據定址特徵中MOD和R/M欄位確定的有效地址計算方法,位移量可以是:
沒有位移量
1位元組位移量disp8
2位元組位移量disp16
立即數部分:總是位於指令編碼的最後1~2位元組
2.單運算元指令編碼格式
2~3位元組,包括操作特徵、定址特徵和位移量三部分
3.與AX或AL有關的指令編碼格式:用於隱含指定AX/AL作為一個運算元的雙運算元指令
4.其它指令編碼格式
如標誌位操作指令、堆疊操作指令等,一般只有一個位元組
第四章 組合語言程式格式
1.組合語言語句種類及其格式
指令語句:每一條指令語句在彙編時都要產生一個可供CPU執行的機器目的碼,又叫可執行語句,
最多可以包含4個欄位。
標號欄位:可選欄位,後面必須有“:”。
標號是一條指令的符號地址,代表了該指令的第一個位元組存放地址。一般放在一個程式段或子程式的入口處,控 製程序的執行轉到該程式位置。在轉移指令或子程式呼叫指令中,可直接引用這個標號
指令助記符欄位
是一條指令的必選項,它表示這條語句要求CPU完成什麼具體操作,如MOV、ADD、SHL等。有些指令還可以在指令助記符的前面加上字首,實現一定的附加操作
運算元欄位
註釋欄位
可選項,該欄位以分號“;“開始,它的作用是為閱讀程式的人加上一些說明性內容,它不會產生機器目的碼,它不會影響程式和指令的功能。
偽指令語句:又叫命令語句,本身並不產生對應的機器目的碼,僅僅是告訴彙編程式對其後面的指令語句和偽指令語句的運算元應該如何處理;可以包含四個欄位:
符號名欄位:可選項。根據偽指令的不同,符號名可以是常量名、變數名、過程名、結構名和記錄名等等;
符號名後面沒有冒號“:”,這是與指令語句的重要區別
偽指令符欄位:必選項,規定了彙編程式所要完成的具體操作
運算元欄位:該欄位是否需要,以及需要幾個是由偽指令符欄位來決定
註釋欄位:可選項,作用與指令語句的註釋欄位相同
識別符號:指令語句中的標號和偽指令語句中符號名統稱為識別符號,由若干個字元構成。
2.組合語言資料
常用的資料形式有:常數、變數和標號
給變數賦初值4種方式:
-
數值表示式。例如:DATA1 DB 32,30H(DATA1的內容為20H,DATA1+1單元內容為30H)
-
?表示式
不帶引號的問號“?”表示可以預置任意內容
-
字串表示式
對於DB偽指令,字串為用引號括起來的不超過255個字元,給每一個字元分配一個位元組單元。字串按從左到右,將字元的ASCII編碼值以地址遞增的排列順序依次存放
-
DUP表示式:重複資料操作符。
DUP還可以巢狀使用,即表示式2又可以是一個帶DUP的表示式
標號:
標號寫在一條指令的前面,它就是該指令在記憶體的存放地址的符號表示,也就是指令地址的別名。
標號主要用在程式中需要改變程式的執行順序時,用來標記轉移的目的地,即作轉移指令的運算元。
每個標號具有三屬性:
段屬性(SEG):即段基值
偏移量屬性(OFFSET):即地址的偏移量
距離屬性(也叫型別屬性):表示該標號可以被段內還是段間的指令呼叫
NEAR(近):該標號只能作段內轉移
FAR(遠):該標號可以被非本段的轉移和呼叫指令使用
3.符號定義語句
1.等值語句,格式:符號名 EQU 表示式
功能:用符號名來表示EQU右邊的表示式。後面的程式中一旦出現該符號名,彙編程式將把它替換成該表示式。表示式可 以是任何形式,常見以下幾種:
常數或數值表示式
地址表示式
變數、暫存器名或指令助記符
2.等號語句,格式:符號名=表示式
功能:與等值語句具有相同的作用,但等號語句可以對一個符號進行多次定義
4.表示式與運算子
操作運算子分為五類:
1.算術運算子:+、—、*、 / 、MOD、SHL、SHR、[ ]
“SHR ”和“SHL”為邏輯移位運算子
下標運算子“[ ]”具有相加的作用。一般使用格式:表示式1 [表示式2]。
作用:將表示式1與表示式2的值相加後形成一個儲存器運算元的地址
2.邏輯運算子:NOT、AND、OR和XOR
3.關係運算符:EQ(等於)、NE(不等於)、LT(小於)、 LE(小於等於)、GT(大於)、GE(大於等於)
如果是常量的比較,則按無符號數進行比較;如果是變數的比較,則比較它們的偏移量的大小。其結果只能是“真”或“假”
4.數值返回運算子:將變數或標號的某些特徵值或儲存單元地址的一部分提取出來
SEG運算子:取變數或標號所在段的段基值
OFFSET運算子:取變數或標號在段內的偏移量
TYPE運算子:取變數或標號的型別屬性,並用數字形式表示。對變數來說就是取它的位元組長度。
LENGTH運算子:取變數的長度。
SIZE運算子:只能作用於變數,SIZE取值等於LENGTH和TYPE兩個運算子返回值的乘積
5.屬性修改運算子:對變數、標號或儲存器運算元的型別屬性進行修改或指定
PTR運算子,格式:型別 PTR 地址表示式
功能:將地址表示式所指定的標號、變數或用其它形式表示的儲存器地址的型別屬性修改為“型別”所指的值。這種修改是臨時的,只在含有該運算子的語句內有效
HIGH/LOW運算子。使用格式:{HIGH|LOW} 表示式
功能:如果表示式為一個常量,則將其分離成高8位和低8位;如果表示式是一個地址(段基值或偏移量)時,則分離出它的高位元組和低位元組
THIS運算子
功能:一般與等值運算子EQU連用,用來定義一個變數或標號的型別屬性。所定義的變數或標號的段基值和偏移量與緊跟其後的變數或標號相同
運算子優先順序:
5.程式的段結構
1.段定義偽指令
1.格式
偽指令SEGMENT和ENDS用於定義一個邏輯段。使用時必須配對,分別表示定義的開始與結束
2.定位型別:用於決定段的起始邊界,即第一個可存放資料 的位置(不是段基址)
PAGE: 表示該段從一個頁面的邊界開始
PARA:表示該段從一個小節的邊界開始
WORD:表示該段從一個偶數字節地址開始,即段起始 單元地址的最後一位二進位制數一定是0
BYTE:表示該段起始單元地址可以是任一地址值
3.組合型別:說明符用來指定段與段之間的連線關係和定位,有六種取值選擇
1.若未指定組合型別,表示本段與其它段無連線關係。在裝入記憶體時,本段有自己的物理段,因此有自己的段基址
2.PUBLIC:在滿足定位型別的前提下,將與該段同名的段鄰接在一起,形成一個新的邏輯段,共用一個段基址。段內的所有偏移量調整為相對於新邏輯段的段基址
3.COMMON: 產生一個覆蓋段。
4.STACK:把所有同名段連線成一個連續段,且系統自動對SS段暫存器初始化為該連續段的段基址。並初始化堆疊指標SP。
5.AT表示式:表示本段可定位在表示式所指示的小節邊界上。表示式的值也就是段基值
6.MEMORY:表示本段在儲存器中應定位在所有其它段之後的最高地址上。如果有多個用MEMORY說明的段,則只處理第一個用MEMORY說明的段。其餘的被視為COMMON。
4.型別名:為某一個段或幾個相同型別段設定的型別名稱
2.段定址偽指令
ASSUME,作用是告訴彙編程式,在處理源程式時,定義的段與哪個暫存器關聯。
一般格式:ASSUME 段暫存器名(CS,DS,ES,SS):段名(段定義偽指令定義的段名),段暫存器名:段名,......
3.段暫存器的裝入
初值(段基值)裝入需要用程式的方法來實現:
DS和ES的裝入:在程式中,使用資料傳送語句來實現對DS和ES的裝入
SS的裝入:
在段定義偽指令的組合型別項中,使用STACK引數,並在段定址偽指令ASSUME語句中把該段與SS段暫存器關聯
如果在段定義偽指令的組合型別中,未使用STACK引數,或者是在程式中要調換到另一個堆疊,這時,可以使用類似於DS和ES的裝入方法
CS的裝入:
CPU在執行指令之前根據CS和IP的內容來從記憶體中提取指令,即必須在程式執行之前裝入CS和IP的值。因此,CS和IP的初始值就不能用可執行語句來裝入
6.過程定義偽指令
在程式設計過程中,常常將具有一定功能的程式段 設計成一個子程式。在MASM巨集彙編程式中,用過程(PROCEDURE)來構造子程式。格式如下:
7.當前位置計數器$與定位偽指令ORG
彙編程式在彙編源程式時,每遇到一個邏輯段,就要為其設定一個位置計數器,它用來記錄該邏輯段中定義的每一個數據或每一條指令在邏輯段中的相對位置。
格式:ORG 數值表示式
作用:將數值表示式的值賦給當前位置計數器$ 。ORG語句為其後的資料或指令設定起始偏移量。
8.編題偽指令TITLE
格式:TITLE 標題名
作用:給所在程式指定一個標題。以便在列表檔案的每一頁的第一行都顯示這個標題。其中標題是使用者任意選用的字串,字元個數不能超過60。
9.從程式返回作業系統的方法
-
使用程式段字首PSP(Program Segment Prefix)實現返回
DOS系統將一個.EXE檔案(可執行檔案)裝入記憶體時,在該檔案的前面生成一個程式段字首PSP,其長度為100H位元組。同時讓DS和ES都指向PSP的開始,而CS指向該程式的程式碼段,即第一條可執行指令。
為了使程式執行完後,正確返回DOS,需要做以下三個操作:
將使用者程式編製成一個過程,型別為FAR 將PSP的起始邏輯地址壓棧,即將INT 20H指令的地址壓棧 在使用者程式結尾處,使用一條RET指令。執行該指令將使儲存在堆疊中的PSP的起始地址彈出到CS和IP中
2.使用DOS系統功能呼叫實現返回
在程式結束時,使用兩條指令:
MOV AH,4CH
INT 21H