星期三, 9月 03, 2008

組合語言站存器介紹

1.通用暫存器

共有四個,其名稱分別是 AX、BX、CX、DX,在組合語言程式中大致沒有太大的差別,但是其中只有 AX ( accumulator,也稱為累加器) 可作為除法或乘法中的被除數與被乘數,當 16 位元不夠大時,常常用 DX:AX 來表示 32 位元。此外這四個暫存器,只有 BX ( base register,也稱為基底暫存器) 可以被作為位址存取之用。CX 也稱為計數暫存器 ( count register),用於計算迴圈之次數或字串處理之次數。DX 也稱為資料暫存器 ( data register),可用來存取埠。

這四個暫存器也可以分成兩個 8 位元的暫存器來使用,例如 AX 可被分成較低的 8 位元稱為 AL,以及較高的 8 位元 AH 來使用。其餘 BX、CX、DX 也都類似。

2.指標與索引暫存器

有五個,其名稱分別是 SP、BP、IP、SI、DI。前面兩個 SP (stack pointer,稱為堆疊指標)與(base pointer,也稱為基底指標)是與堆疊(stack)有關的暫存器,以獲得詳細的堆疊資料。堆疊是一塊區域,用來暫時存放資料之用,在 8086/8088 中,堆疊是由最高位址中開始存放,每次都必須存入一個字組的長度,並用一組指標,來表示堆疊已經使用到那兒了,這組指標就是 SS:SP。也就是說,當成是要將資料存入堆疊時,該資料應該存放在 SS:SP 所指的位址再低 2 個位元組,然後 CPU 再使 SP 之內容減 2,使 SP 再指到下一個未使用的空間。

那什麼情形會要將資料存入堆疊內呢?有好幾種情形,例如呼叫副程式時,會預先把返回位址存入堆疊﹔呼叫中斷時也是如此。BP 通常用於呼叫副程式時,傳遞參數之用。

IP (instruction pointer,稱為指令指標) 配合 CS 變成 CS:IP,指向將要執行的 8086/8088 位址。當 CPU 要執行程式時,必須到記憶體去提取要執行的指令,而要到那一個記憶體位址去提取指令呢?這時 CPU 就會到 CS:IP 指到的位址去提取。在程式中,一般是沒有辦法改變 CS:IP 的值,除非是跳躍 (jmp、jz等) 指令或是呼叫 (call、ret等) 指令。

SI (source index,稱為來源索引暫存器) 和 DI (destination index,稱為目的索引暫存器) 通常是用來當作位址指標,也可用作加減法。這五個暫存器,每一個都不能分開來當作兩個 8 位元的暫存器使用。

3.區段暫存器

有 CS、DS、ES、SS 四個,分別表示程式碼(code segment register)、資料(data segment register)、額外(extra segment register)、堆疊(stack segment register)區段之用。在 DOS 系統中,每一個區段容量只有 64KBytes。

當資料區段不夠用時,就可以用額外區段來補足,例如想要將一個區段的某些內容複製到另一區段中,就可以同時指定 DS、ES 分別表示這兩個區段。

4.旗標暫存器

旗標暫存器 (flag register) 是一個 16 位元的暫存器,但只有其中九個位元有用到,它們分散在這十六個位元中,採用這種分散方式是為了與舊式的 8080 CPU 的旗標相同。這 9 個旗標可分為三類:狀態旗標 ( status flag )、控制旗標 ( control flag ) 與系統旗標 ( system flag )。狀態旗標包含 CF、PF、AF、ZF、SF 和 OF,它們會受到算術、比較或邏輯運算結果狀態的影響,而使旗標被設定 ( set,其值為 1 ),或被清除 ( clear,其值為零 )。第 10 位元的 DF 用來控制掃描、搬移、搜尋字串的方向,屬於控制旗標。至於 IF、TF 為設計作業系統、除錯時才需要用到,屬於系統旗標,一般應用程式很少使用。底下簡單介紹這些旗標:

名稱

位元

狀態

說明

進位旗標
carry flag
CF

0 CF=1,CY
CF=0,NC

當運算發生進位或借位時,ZF 被設為 1;反之設為 0。例如兩數相加:

        mov     ax,8000h
        add     ax,8000h

8000h+8000h 應為 10000h,發生進位,雖然 AX 為 0,但是會使 CF 設為一,表示進位。

同位旗標
parity flag
PF

2 PF=1,PE
PF=0,PO
運算的結果換成二進位後,最低的 8 個位元中,若有偶數個 1,則此位元設為 1,反之為 0。

輔助進位旗標
auxiliary carry flag
AF

4 AF=1,AC
AF=0,NA
當運算過程中,第 3 位元與第 4 位元之間發生進位或借位時,AF 被設為 1,否則被設為 0,常用於 BCD 的運算。

零旗標
zero flag
ZF

6 ZF=1,ZR
ZF=0,NZ
運算結果為零時,ZF 會被設定為 1。若比較相同兩數, ZF 也會被設為一,若比較不相同的兩數,ZF 會被清除為零。例如:
        mov     ax,8000h
        add     ax,8000h

相加後,AX 為零,故 ZF 設為一。

符號旗標
sign flag
SF

7 SF=1,NG
SF=0,PL
運算結果的最高位元為 1 時,SF 會被設為 1 ( 表示負數 ),否則被清除。

陷阱旗標
trap flag
TF

8   用於單步追蹤除錯時,所以也稱為追蹤旗標 ( trace flag ),例如在 MS-DOS 的 DEBUG 中,就是利用 TF 達到單步追蹤的目的。當 TF 設為一時,每執行一個指令便會發生中斷,此中斷就將執行該指令後暫存器列出。

中斷旗標
interrupt flag
IF

9 IF=1,EI
IF=0,DI
當 IF 被設定時,可遮罩的硬體中斷才能使 CPU 產生中斷效果;反之所有可遮罩的硬體中斷均會被抑制。但是不可遮罩中斷以及 CPU 產生的例外卻完全不受 IF 影響。

方向旗標
direction flag
DF

10 DF=1,DN
DF=0,UP
當 DF 被清除時 ( 即 DF=0 ),處理字串的索引暫存器會遞增,往高位址方向處理,反之則遞減。

溢位旗標
overflow flag
OF

11 OF=1,OV
OF=0,NV

當運算結果無法容納於目的運算元中,此旗標會被設為一。大致可分三種情形:(1)兩同號數相加或兩異號數相減,(2)乘除運算時,所得的積或商超過運算元存放範圍,在移位或旋轉指令時,最高位元值受到更動 ( 0 變成 1 或 1 變成 0 )。

在此列出 DEBUG 中執行 r 指令後的意義:

-r [Enter]
AX=0000  BX=0000  CX=0025  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=10F7  ES=10F7  SS=10F7  CS=10F7  IP=0100   NV UP EI PL NZ NA PO NC
10F7:0100 EB19           JMP    0119

英文字母NV UP EI PL等等就是旗標的狀態,請看下表:

旗標名稱 設定(1) 清除(0)
CF,進位(是/否)
PF,同位(偶數/基數)
AF,輔助進位(是/否)
ZF,零(是/否)
SF,符號(是/否)
IF,中斷(允許/抑制)
DF,方向(遞減/遞增)
OF,溢位(是/否)
CY
PE
AC
ZR
NG
EI
DN
OV
NC
PO
NA
NZ
PL
DI
UP
NV

沒有留言: