[MASM學習筆記]第一課:數字系統與暫存器
電腦記憶體空間的基本單位
電腦記憶體空間的最小單位為Bit(位元),1 bit只能有1與0兩種邏輯狀態。一個採用ASCII編碼的半形文字或符號所佔用的記憶體空間大小為8 bits(8位元),為1 byte(1個位元組)。而一個全形文字所佔用的記憶體空間大小為16 bits(16位元),等於2 bytes(2個位元組),稱為1 word,字組觀念將在後面做介紹。
換算方式如下:
1byte = 8bits
1 KB = 210 bytes = 1024 bytes
1 MB = 220 bytes = 1024 Kbytes
1 GB = 230 bytes = 1024 Mbytes
1 TB = 240 bytes = 1024 Gbytes
注意電腦使用的K、M、G等等的單位符號並非數學上以10為底數的整數乘冪值(如103、106、109),而是以2為底數的近似值(如210、220、230)作為基準。
字組關係
字組就是在一個位址下所能用來儲存資料的記憶體空間大小。組合語言中可以利用字組來定義一個變數的記憶體空間。
Byte:8 bits(1 byte),在組合語言中的語法為「DB」(Define Byte)。
Word:16 bits(2 bytes),在組合語言中的語法為「DW」(Define Word)。
Dword:32 bits(4 bytes), 在組合語言中的語法為「DD」(Define Double Word)。
Qword:64 bits(8 bytes), 在組合語言中的語法為「DQ」(Define Quadruple Word)。
暫存器(Register)
什麼是暫存器?
暫存器位於中央處理器(CPU)內部,用來暫存指令、位址或是一些數據。暫存器的種類很多種,有累加器、基底暫存器、計數暫存器、資料暫存器、來源索引暫存器、目的索引暫存器、指令指標暫存器、堆疊指標暫存器、基底指標暫存器、堆疊指標暫存器、程式區段暫存器、資料區段暫存器、額外區段暫存器、堆疊區段暫存器,與旗標暫存器。這些暫存器在之後都會做簡略的介紹。
80X86相容的CPU內部暫存器
由於我只有學過80X86 16位元的組合語言程式,故在此只列出16位元的暫存器。暫存器可依功用分為以下幾種類型,這些都要背!
- 通用暫存器:AX、BX、CX、DX
- 指標索引暫存器:SP、BP、SI、DI、IP
- 區段暫存器:CS、DS、ES、SS
- 旗標暫存器:Flag
AX 累加器(Accumulator)
分為AH(8 bits)和AL(8bits)兩部份,共16 bits,如下圖。
AX可用來做加減乘除運算、邏輯運算、字串運算,或是I/O處理。
BX 基底暫存器(Base Register)
分為BH(8 bits)和BL(8bits)兩部份,共16 bits,如下圖。
BX可用來進行資料運算,或是加強索引及定址功能。可以直接當作記憶體位址的基底運算元。
CX 計數暫存器(Count Register)
分為CH(8 bits)和CL(8bits)兩部份,共16 bits,如下圖。
CX可用來進行資料運算、存放迴圈次數、字串處理的重複次數、資料位移或是旋轉的次數。
DX 資料暫存器(Data Register)
分為DH(8 bits)和DL(8bits)兩部份,共16 bits,如下圖。
DX可用來進行資料運算、乘除運算,或是拿來存放I/O的位址。
SP 堆疊指標暫存器(Stack Pointer)
共16 bits,如下圖。
SP永遠指向堆疊頂端的最新資料儲存位址。當堆疊資料有進(PUSH)出(PUP)時,SP的位址也會隨之加減更動。
BP 基底指標暫存器(Base Pointer)
共16 bits,如下圖。
BP可以指向堆疊的任何位置,也能用來做間接定址、運輸和運算。
IP 指令指標暫存器(Instruction Pointer)
共16 bits,如下圖。
IP用來指向指令的所在位置,一旦CPU執行完IP所指的指令後,IP便會再指向到下一個指令,讓CPU去讀取執行。負責掌管CPU執行程式的流程。
SI 來源索引暫存器(Source Index)
共16 bits,如下圖。
SI作為資料來源的記憶區索引。
DI 目的索引暫存器(Destination Index)
共16 bits,如下圖。
DI作為資料目的地的記憶區索引。
CS 程式區段暫存器(Code Segment)
共16 bits,如下圖。
CS用來存放程式指令的位址。若配合IP(CS:IP)使用,可以得到指令存放的實際位址。
DS 資料區段暫存器(Data Segment)
共16 bits,如下圖。
DS用來存放及設定資料的位址。若配合SI(DS:SI)使用,可以得到資料存放的實際位址。
ES 額外區段暫存器(Extra Segment)
共16 bits,如下圖。
若DS資料太多(超過64 Kbytes)時,可以使用ES來存放資料。若要進行字串運算,必須配合DI來使用。
SS 堆疊區段暫存器(Stack Segment)
共16 bits,如下圖。
SS用來存放堆疊的位址。若配合SP(SS:SP)使用,可以得到堆疊內存放資料的實際位址。有關堆疊的觀念會在之後的章節做介紹。
旗標暫存器(Flag Register)
共16 bits,但只有9個位元被使用,如下圖。
旗標依用途可以分為表示狀態的「狀態旗標」和控制程序的「控制旗標」,分別如下:
- 狀態旗標:CF、PF、AF、ZF、SF、OF
- 控制旗標:TF、IF、DF
以下旗標變化範例均以8位元運算來說明。
CF(Carry Flag) 進位旗標
在加減運算後,當最高位元(MSB)有進位或借位時,CF=1;否則CF=0。
範例一:10001011(2) + 01011001(2) = 01100100(2),最高位元沒有進位,因此CF=0。
範例二:10110011(2) + 10101100(2) = 101011111(2),最高位元有進位,因此CF=1。
PF(Parity Flag) 奇偶旗標
PF用來判斷指令在算術或邏輯運算後之結果值二進制數最低8個位元的1數量。若有奇數個1,則PF=0;偶數個1則PF=1。
範例一:10001011(2) + 01011001(2) = 011100100(2),因為有偶數個1,因此PF=1。
範例二:10110011(2) + 10101000(2) = 101011011(2),因為有奇數個1,因此PF=0。
AF(Auxiliary Flag) 輔助進位旗標
在算術或邏輯運算後,若第3位元(從0算起)產生進位或是借位,則AF=1;否則AF=0。
範例一:10001011(2) + 01011001(2) = 011100100(2),發生進位,因此AF=1。
範例二:10110011(2) + 10101000(2) = 101011011(2),沒發生進位,因此AF=1。
ZF(Zero Flag) 零旗標
在算術或邏輯運算後,若結果為零,則ZF=1;否則ZF=0。
範例一:10001011(2) + 01011001(2) = 11100100(2),結果值不為零,因此ZF=0。
範例二:11111111(2) + 00000001(2) = 100000000(2),結果值為零(但有進位),因此ZF=1。
SF(Sign Flag) 符號旗標
在算術或邏輯運算後,若最高位元(MSB)為1,則SF=1,可用來表示為負數;否則SF=0,可用來表示為正數。
範例一:10001011(2) + 01011001(2) = 11100100(2),結果值最高位元為1,因此SF=1。
範例二:11111111(2) + 00000001(2) = 100000000(2),結果值最高位元為0,因此ZF=0。
OF(Overflow Flag) 溢位旗標
在算術運算後,當結果發生溢位時,則OF=1;否則OF=0。判斷溢位最簡單的方法就是看他是否由正轉負或是負轉正,且只有正加正或是負加負才會有溢位的可能。
範例一:11001011(2) + 01011001(2) = 100100100(2),雖有進位,但負加正不可能發生溢位,因此OF=0。
範例二:10111111(2) + 10000001(2) = 101000000(2),負加負變為正,發生溢位,因此OF=1。
TF(Trap Flag) 單步旗標
主要用於除錯(Debug)作業,若TF=1,則程式執行時將一次執行一個指令。
DF(Direction Flag) 方向旗標
主要用於字串運算,若DF=0,做字串運算時,CPU會由低位址的字串處理到高位址字串;若DF=1,則反之。
IF(Interrupt Flag) 中斷旗標
當IF=1時,CPU可以接受外部的中斷;IF=0時,則無法接受外界中斷。
結論
暫存器的縮寫在組合語言中相當常用,撰寫組合語言前務必要把暫存器的名稱和功用背好,否則根本無法繼續下去。