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

組合語言前四章學習筆記

學習 組合語言程式設計 筆記

第一章 組合語言的一般概念

1.1計算機程式設計語言可分為:

   機器語言
機器能夠識別的語言,把各種命令和資料用二進位制直接表示
比較簡單,但是人不好理解,它直接表示了計算機內部的基本操作,所以機器語言程式執行效率最高,但是不便於理解記憶
   高階語言
更類似於自然語言,簡單但是效率較低
   組合語言
在一些場合我們要使用效率高的語言來執行特殊操作,但又不希望使用機器語言
程式與機器語言程式相對應,效率也是相同的
與硬體密切相關
對於不同型別計算機來講有不同的機器指令系統和組合語言
對於一臺計算機來說,機器語言的執行主要取決於計算機的CPU

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

   1.可以根本上認識、理解計算機工作過程
   2.在計算機系統中,某些功能必須用匯編語言程式實現
   3.組合語言效率高於高階語言程式

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

    進位計數制:
進位計數制是利用固定的數字符號和統一的規則來計數的方法。
權:權是基數的冪,表示數碼在不同位置上的數值
基數:每個數位上能使用不同數碼的個數稱為基數,例如十進位制基數為10,二進位制基數為2
數碼:一組用來表示某種數制的符號。例如,十進位制的數碼是0~9;
權*對應位置數碼=該位置數值大小
因為二進位制不便於書寫和閱讀,因此書寫時常使用8進位制和16進位制
為了區分不同進製表示,於是人們在數尾用一個字母表示相應進位制:(注:未使用字母時,預設十進位制)
       >B ——二進位制
       >O ——八進位制
       >D ——十進位制
       >H ——十六進位制
      數制間轉換:
1.十進位制轉二進位制
       (1)減權定位
	從二進位制數高位起,依次用待轉換的十進位制數與各位權值進行比較;如果夠減,則該數位係數Ki=1,同時減去該位權值,餘數作為下一次比較的值。
       (2)除基取餘法(也適用於其他數制)
	將十進位制數除以基數2,其餘數為二進位制數的最低位,再用其商除2,其餘數為次低位,反覆直到商為0
2.十進位制小數轉二進位制數
       (1)減權定位
           (2)乘積取整法
	用2乘十進位制小數,可以得到積,將積的整數部分取出,再用2乘餘下的小數部分,又得到一個積,再將積的整數部分取出,如此進行,直到積中的小數部分為零,或者達到所要求的精度為止。 然後把取出的整數部分按順序排列起來,先取的整數作為二進位制小數的高位有效位,後取的整數作為低位有效位。

3.二進位制整數轉換為十進位制數
       (1)按權相加法
       (2)逐次乘基相加法
4.二進位制小數轉換為十進位制數
       (1)按權相加
	從第一位開始依次乘2^-1、2^-2……最後相加
       (2)逐次除基相加法
5.二進位制與八進位制和十六進位制間的轉換
          三位二進位制數對應一位八進位制數,四位二進位制數對應一位十六進位制數

1.4帶符號數的表示

用“+”或“-”表示正負的數叫真值
用“0”或“1”表示的數叫機器數(計算機中用這種表示)
帶符號的機器數可以用原碼、反碼和補碼三種不同的碼值來表示。一般計算機用補碼來表示。
(1)原碼的表示
         最高位表符號位,0為正,1為負
(2)補碼的表示
(3)補碼數的表示範圍
           當位數為8,最大為01111111(+127),最小為10000000(-128)
           0的補碼只有一個,000000000
(4)補碼加減

1.5字元的表示

    在計算機內部,各種字元都是按照一定的方式編寫成二進位制資訊的,不用的計算機以及場合用的編碼形式不同。目前最廣泛的是ASCII碼。

1.6基本邏輯運算

   (1)與 ∧
   (2)或∨
   (3)非
   (4)“異或”運算 ⨁

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

2.1IBM-PC微機的基本結構

一.微機的一般構成

   一般計算機包括的五大部件:運算器、控制器、儲存器、輸入裝置和輸出裝置。

微機將運算器和控制器整合在一個積體電路晶片上,稱為中央處理器CPU。
系統採用匯流排結構,有較大的靈活性和擴充套件性。
系統匯流排由地址匯流排、資料匯流排和控制匯流排構成。(起控制和傳輸作用)

   (1)中央處理器CPU
微計算機的中央處理器也叫微處理器,包括控制和運算器。
起分析從主儲存器取來的各條指令的功能,控制計算機各部件完成指定功能的各項操作。
   (2)主儲存器
存放程式和資料,由若干儲存單元構成。
儲存單元多少表示儲存器容量,每個儲存單元有唯一編號標識,稱為儲存單元的地址;對其的存取也是通過地址訪問的。
計算機儲存資訊的基本單位是一個二進位制位,可存一個二進位制數0、1。每8個組成一個位元組;大多數計算機中儲存器的組織都是以位元組為基本單位,每個稱為一個儲存單元。
習慣上CPU+主儲存器=主機
一般計算機中,除了主儲存器還有輔存,由於其在計算機之外,因此也叫外存。
   (3)輸入輸出裝置及介面
將外部資訊輸入計算機
由於不同I/O裝置之間的工作速度、工作原理以及所處理的資訊格式等與主機相差很大,因此I/O裝置要通過I/O介面與系統匯流排連線。
   (4)系統匯流排
地址、資料、控制匯流排

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

     組合語言程式由指令構成,指令是其基本單位。
     CPU執行指令程式就是在重複執行:從儲存器取指令、執行指令操作。這兩個步驟執行方式又分為序列方式和指令流水線方式。
     (1)序列方式
     (2)指令流水線方式
流水線方式工作的計算機有較高的工作效率,可以有效充分利用各種硬體資源。
這種結構最先出現在Intel8086/8088CPU中,要實現該方式,CPU組成結構要劃分為多個單元
執行單元EU:分析和執行指令
匯流排介面單元BIU:負責CPU與儲存器、I/O的資訊傳送	
這兩個是獨立又分工的獨立部分,在一定程度上並行工作完成不同任務。

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

   1.  8個通用暫存器、2個控制暫存器以及4個段地址暫存器
   2.如下,H為高位、L為低位:
   3.通用暫存器
(1)資料暫存器:包括AX、BX、CX、DX四個暫存器,用於存放運算元或運算結果。
            e.g. MOV AX,BX
(2)指標暫存器:堆疊指標SP和基址指標BP
(3)變址暫存器:兩個16位的變址暫存器,源地址暫存器SI和目的地址暫存器DI。
   4.段暫存器
8086/8088CPU在使用儲存器時,將其分為若干段,每段放不同的內容(程式程式碼、資料),每一段用一個段暫存器指名起始位置(段基址)。
程式碼段暫存器CS、資料段暫存器DS、堆疊段暫存器SS、附加段暫存器ES
    5.指令指標IP
CPU從儲存器取指令時,以CS作為程式碼段的基址指標,以IP內容為偏移量,共同形成指令存放地址
當CPU取出指令後,IP內容自動修改為指向下一條指令
IP的內容既不能用指令去讀取,也不能用指令賦值。只能通過某些指令的執行而自動修改
    6.標誌暫存器
用來反映CPU執行時的某些狀態。

2.3儲存器的組織結構

  ###一.儲存器的組成
1.由若干儲存單元組成
2.每個單元放相同長度的二進位制數
3.每個儲存單元有唯一一個地址編號——地址
4.任何兩個相鄰位元組單元就夠成一個字單元
5.在定義一個地址時必須指出是位元組或者字型別屬性

  ###二.儲存器的段結構
8086/8088CPU的儲存結構特點:
      將1MB的儲存空間劃分為若干個段,每個段最大長度為64KB、
      每個段的基址必須是一個小節的首地址、
      邏輯段在物理儲存器中可以是鄰接的、間隔的、部分重疊的和完全重疊的、
      在任意時刻,一個程式只能訪問4個當前段中的內容。

  ###三.邏輯地址與實體地址及對應關係
1.實體地址
2.邏輯地址
在程式設計中,為了便於程式的開發和對儲存器進行動態管理,使用邏輯地址。包含段基值和偏移量兩個部分
3.邏輯地址轉換為實體地址
將邏輯地址的端基值左移4位,形成20位的段基址(低4位為0)然後與16為的偏移量相加,結果即為20位的實體地址
4.邏輯地址來源

2.4堆疊及其操作方法

   堆疊是一個特定的儲存區,訪問該儲存區一般需要按照專門的規則進行操作
   堆疊的用途:主要用於暫存資料以及在過程呼叫或處理中斷時儲存斷點資訊

   ###一.堆疊的構造
分為專門堆疊儲存器(按堆疊工作方式專門設計的)、軟體堆疊(由設計人員在記憶體中劃出。注:8086/8088採用該方式)
在堆疊中存取資料規則為“先進後出FILO”
   ###二.堆疊的組織
以8086/8088為例,資料在堆疊中以字(兩位元組)為單位存放,資料的低8位放在較低地址單元,高8位放在較高地址單元。
   ###三.堆疊操作
1.設定堆疊
       主要是對堆疊暫存器SS和堆疊指標SP賦值
       e.g STACK1 SEGMENT PARA STACK DB100 DUP (0)      STACK1 ENDS
       PARA STACK說明本段為堆疊段,在程式經彙編、連線並裝入記憶體時,系統將自動為其分配一個儲存區作為堆疊段。
2.進棧PUSH
       把資料存入堆疊
       e.g PUSH AX
3.出棧POP
      出棧操作由POP指令或機器自動實現,它從堆疊頂部彈出一個字到通用暫存器、段暫存器或字儲存單元
      e.g POP AX

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

3.1定址方式

  1.一條指令由操作碼和運算元兩部分組成
   操作碼:表示該指令應完成的具體操作,如加法、減法、乘法、移位等,在組合語言中使用一定的符號表示,稱為助記符。如ADD、PUSH、POP、MOV等
   運算元:操作碼的操作物件
  2.定址方式:尋找指令中所需運算元的各種方法,也就是提供指令中運算元的存放資訊的方式
  3.Intel 8086/8088各指令中提供運算元的方法有一下四種:
(1)立即數運算元——運算元在指令程式碼中提供
(2)暫存器運算元——運算元在CPU的通用暫存器或段暫存器中
(3)儲存器運算元——運算元在記憶體的儲存單元中
(4)I/O埠運算元—— 運算元在輸入/輸出介面的暫存器中
  4.立即數定址  運算元作為指令的一部分而直接寫在指令中,這種運算元稱為立即數,這種定址方式也就稱為立即數定址方式。    	
  5.儲存器定址  指令所要的運算元已儲存在某暫存器中,或把目標運算元存入暫存器。把在指令中指出所使用暫存器(即:暫存器的助憶符)的定址方式稱為暫存器定址方式。由於存取暫存器運算元完全在CPU內部進行,不需要匯流排週期,所以速度很快。
一個儲存單元邏輯地址表示方式: 段基址: 偏移量    段基址由某個暫存器提供;偏移量表示了該儲存單元與段起始地址之間的距離,也叫有效地址EA。
EA由位移量、基址、變址三種地址分量組合,再由CPU執行單元EU計算出來。
  6.直接定址  指令所要的運算元存放在記憶體中,在指令中直接給出該運算元的有效地址,這種定址方式為直接定址方式。在這種方式的指令中,有效地址EA只有位移量地址分量。
在組合語言中,直接定址方式用符號或常數來表示
1)用符號表示
MOV BX,VAR;表示將資料段中,偏移了VAR個位元組距離的字單元內容送到暫存器BX中
2)用常數來表示
MOV AX,DS:[64H](不加方括號則表示將100送到AX中)表示從當前資料段開始,偏移100個位元組的字單元內容送到AX中。不能寫為MOV AX,64H,一定要帶方括號	
注意:立即定址方式和直接定址方式的書寫格式的不同,直接定址的地址要寫在括號“[”,“]”內。在程式中,直接地址通常用記憶體變數名來表示,如:MOV BX, VARW,其中,VARW是記憶體字變數。
    試比較下列指令中源運算元的定址方式(VARW是記憶體字變數):MOV AX,1234H MOV AX, [1234H] ;前者是立即定址,後者是直接定址 MOV   AX, VARW           MOV AX, [VARW] ;兩者是等效的,均為直接定址
  7.暫存器間接定址方式:
運算元在暫存器中,運算元有效地址在SI、DI、BX、BP這四個暫存器之一中。在不使用段超越字首的情況下,如果有效地址在SI、DI和BX中,則以DS段暫存器中的內容為段值。如果有效地址在BP中,則以SS段暫存器中的內容為段值。
  8.暫存器相對定址方式:
運算元在儲存器中,運算元的有效地址是一個基址暫存器(BX、BP)或變址暫存器(SI、DI)的內容加上指令中給定的8位或16位位移量之和。
  9.基址加變址定址方式:
運算元在暫存器中,運算元的有效地址由:
基址暫存器之一的內容與變址暫存器之一的內容相加BX   SI  即: EA = BP+ DI在一般情況下,如果BP之內容作為有效地址的一部分,則以SS之內容為段值,否則已DS為段值。
例如:MOV AX,[BX][DI]   如:(DS)=2100H,(BX)=0158H,(DI)=10A5H,則EA=0158 + 10A5 = 11FD   實體地址=21000 + 11FD = 221FDH  221FDH地址中的內容:1234H  執行該指令後AX = 1234H
  10.相對基址加變址定址方式:
運算元在儲存器中,運算元的有效地址由於基址暫存器之一的內容與變址暫存器之一的內容及指令中給定的8位或16位位移量相加得到。
  11.I/O埠定址
在計算機系統,對I/O埠的定址方式有儲存器編址方法和I/O埠編址方法兩種方法
儲存器編址方法、I/O埠編址方法(8086/8088系統採用方式)

3.2指令系統

  ###1.一種計算機所能執行的各種型別的指令的集合稱為該計算機的指令系統
  Intel8086/8088CPU指令系統指令分為六大類:傳送類指令、算術運算類指令、位操作類、串操作類、程式轉移類、處理器控制類。
  ###2.從指令的格式劃分,一般可以分為三種:
雙運算元指令:OPR DEST SRC
單運算元指令:OPR DEST
無運算元指令:OPR

3.3指令編碼

  ###1.彙編:
    將組合語言程式轉換為機器語言程式的過程
  ###2.彙編程式:
    在計算機中實現彙編過程的系統程式
  ###3.Intel8086/8088彙編指令的編碼格式有四種基本格式:
雙運算元指令編碼格式
單運算元指令編碼格式
與AX或AL有關的指令編碼格式
其它指令編碼格式
    如標誌位操作指令、堆疊操作指令等。這些指令的編碼格式一般只有一個位元組

第四章 組合語言程式格式

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

  組合語言的語句可以分為指令語句和偽指令語句
  一、指令語句
每一條指令語句在彙編時都要產生一個可以供CPU執行的機器目的碼,又叫可執行語句。   
一般格式為:標號:指令助記符,運算元,;註釋(四個欄位)
(1)標號:
這是指令語句中的可選欄位。如果一條語句中定義標號,必須以“:”作為結束符。一個標號是一條指令的符號地址,它代表該指令的第一個位元組地址。因此,一個程式段或子程式的入口處,通常設定一個標號。當程式需要轉入該程式時,在轉移指令或呼叫子程式指令中,可直接引用這個標號。e.g ADDR1:MOV AL ,100中的ADDR1。
(2)操作符(指令助記符):
指令操作符和偽指令符是語句中不可省略的主要成分。指令操作符就是指令的助記符,如 MOV、ADD、SHL 等,它表示該語句要求 CPU 完成的具體操作。偽指令符可以是資料定義偽指令、段定義偽指令、過程定義偽指令、程式連線偽指令等,它們是要求彙編程式在對源程式進行彙編時進行何種操作的命令。
(3)運算元及引數
指令語句的運算元是指令操作的物件。不同的指令,要求的運算元個數不同,可以是一個、兩個或無運算元。偽指令語句引數的個數也因不同的偽指令而異,這些引數可以是一個常數、字串,以及一些專用符號等,它們是偽指令語句命令的型別及命令格式等說明引數。有時偽指令的引數可以省略。如ADD和MOV需要兩個。
(4)註釋欄位
這是一個任選欄位。註釋欄位必須以分號“;”開始,它可對程式或指令加以註解,提高程式的可讀性。當需要作較多的文字說明時,註釋可以獨佔一行或多行,但每行第一個有效字元必須是分號。註釋欄位的內容不影響程式和指令的功能,它也不出現在機器目的碼中。

  二、偽指令語句
又叫命令語句,偽指令本身並不產生對應的機器目的碼。它僅僅是告訴彙編程式對其後面的指令語句和偽指令語句的運算元應該如何處理。一條偽指令語句可以包含四個欄位:
(1)符號名欄位
該欄位為可選項。根據偽指令的不同,符號名可以是常量名、變數名、過程名、結構名和記錄名等等,符號名後面沒有冒號“:”,這是與指令語句的重要區別!
(2)偽指令符欄位
(3)運算元欄位
(4)註釋欄位為可選項,該欄位必須以分號開始。其作用與指令語句的註釋欄位相同

4.2組合語言資料

 1. 資料是指令和偽指令語句中運算元的基本組成部分。一個數據由數值和屬性兩部分構成
 2 .在組合語言中常用的資料形式有:常數、變數和標號
常數
在彙編期間其值已完全確定,並且在程式執行過程中,其值不會發生變化
可以用在以下幾種情況
       作指令語句的源運算元
       在指令語句的直接定址方式、變址(基址)定址方式或基址變址定址方式中作位移量
       在資料定義偽指令中使用
變數
變數用來表示存放資料的儲存單元,這些資料在程式執行期間可以被改變
程式中以變數名的形式來訪問變數,因此,可以認為變數名就是存放資料的儲存單元地址
變數被定義後有以下三個屬性:
       段屬性
       偏移屬性
       型別屬性
標號
標號寫在一條指令的前面,它就是該指令在記憶體的存放地址的符號表示,也就是指令地址的別名;標號主要用在程式中需要改變程式的執行順序時,用來標記轉移的目的地,即作轉移指令的運算元

4.3 符號定義語句

  在源程式設計中,使用符號定義語句可以將常數或表示式等內容用某個指定的符號來表示。
  8086/8088組合語言中有兩種符號定義語句:
1.等值語句。語句格式:符號名 EQU 表示式
2.等號語句。語句格式:符號名=表示式
功能:與等值語句具有相同的作用。但等號語句可以對一個符號進行多次定義

4.4表示式與運算子

   1.表示式:
   定義:常數、符號、暫存器等通過運算子連線起來的式子。
   對錶達式的運算不是CPU完成的,而是在彙編時彙編程式運算的。
   2.運算子:
   可分為以下幾類:
(1) 算術運算子


(2)邏輯運算子

(3)關係運算符

(4)數值返回符

(5) 修改屬性符

(6)其他

(7)優先順序

4.5程式的段結構

   8086/8088在管理記憶體時,按照邏輯段進行劃分, 不同的邏輯段可以用來存放不同目的的資料。在程式 中使用四個段暫存器CS,DS,ES和SS來訪問它們。在源程式設計時,使用偽指令來定義和使用這些邏輯段。
   一、段定義偽指令
  偽指令SEGMENT和ENDS用於定義一個邏輯段。使用時必須配對,分別表示定義的開始與結束。

  段定義偽指令語句各部分的作用如下:
1、段名
段名是由使用者自己任意選定的,符合識別符號定義規則的一個名稱。
2、定位型別
定位型別用於決定段的起始邊界,即第一個可存放資料的位置(不是段基址)。它可以有4種取值。
3、組合型別
組合型別說明符用來指定段與段之間的連線關係和定位。它有六種取值選擇。
(1)若未指定組合型別,表示本段與其它段無連線關係。在裝入記憶體時,本段有自己的物理段,因此有自己的段基址
(2 )PUBLIC:在滿足定位型別的前提下,將與該段同名的段鄰接在一起,形成一個新的邏輯段,共用一個段基址。段內的所有偏移量調整為相對於新邏輯段的段基址。
(3)COMMON:產生一個覆蓋段。在多個模組連線時,把該段與其它也用COMMON說明的同名段置成相同的段基址,這樣可達到共享同一儲存區。共享儲存區的長度由同名段中最大的段確定。	
(4)STACK:把所有同名段連線成一個連續段,且系統自動對SS段暫存器初始化為該連續段的段基址。並初始化堆疊指標SP。使用者程式中應至少有一個段用STACK說明,否則需要使用者程式自己初始化SS和SP。
(5)AT表示式:表示本段可定位在表示式所指示的小節邊界上。表示式的值也就是段基值。
(6)MEMORY:表示本段在儲存器中應定位在所有其它段之後的最高地址上。如果有多個用MEMORY說明的段,則只處理第一個用MEMORY說明的段。其餘的被視為COMMON
4.類別名
類別名為某一個段或幾個相同型別段設定的型別名稱。系統在進行連線處理時,把類別名相同的段存放在相鄰的儲存區,但段的劃分與使用仍按原來的設定。

類別名必須用單引號引起來。所用字串可任意選定,但它不能使用程式中的標號、變數名或其它定義的符號。
在定義一個段時,段名是必須有的項,而定位型別、組合型別和類別名三個引數是可選項。各個引數之間用空格分隔。各引數之間的順序不能改變。

   二、段定址偽指令
   段定址偽指令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偽指令來結束。
(2)在程式執行期間,當執行某些指令時,CPU自動修改CS和IP,使它們指向新的程式碼段。

4.6過程定義偽指令

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

   過程名 PROC [NEAR/FAR]
          ...... RET ......
   過程名 ENDP

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

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

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

在源程式中,使用符號S來表示位置計數器的當前值。因此,S被稱為當前計數器。它位於不同的位置具有不同的值。
位置計數器S在使用上完全類似變數的使用.

4.8編題偽指令TITLE

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

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

   為了使程式執行結束後,能夠正確地返回到作業系統,需要在程式中加上一些必要的語句。一般有以下兩種方法:
(1)使用程式段字首PSP(Program Segment Prefix)實現返回
(2)使用DOS系統功能呼叫實現返回