8086/8087寄存器(转载自小木偶)

8086 暫存器

暫存器是在 CPU 中一個暫時儲存資料的地方。它有點兒像記憶體(DRAM),但是不像記憶體這麼多,暫存器只有一個、兩個或四個位元組的大小而已。 CPU 可以對暫存器作加、減、乘、除、且、或等等運算。8086/8088 共有 14 個 16 位元的暫存器,其名稱都以兩個英文字表示,大致可分為以下四類。

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 也都類似。

堆疊的部份,以獲得詳細的堆疊資料。堆疊是一塊區域,用來暫時存放資料之用,在 8086/8088 中,堆疊是由最高位址中開始存放,每次都必須存入一個字組的長度,並用一組指標,來表示堆疊已經使用到那兒了,這組指標就是 SS:SP。也就是說,當成是要將資料存入堆疊時,該資料應該存放在 SS:SP 所指的位址再低 2 個位元組,然後 CPU 再使 SP 之內容減 2,使 SP 再指到下一個未使用的空間。

堆疊的部份,以獲得詳細的堆疊資料。堆疊是一塊區域,用來暫時存放資料之用,在 8086/8088 中,堆疊是由最高位址中開始存放,每次都必須存入一個字組的長度,並用一組指標,來表示堆疊已經使用到那兒了,這組指標就是 SS:SP。也就是說,當成是要將資料存入堆疊時,該資料應該存放在 SS:SP 所指的位址再低 2 個位元組,然後 CPU 再使 SP 之內容減 2,使 SP 再指到下一個未使用的空間。 有五個,其名稱分別是 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 的旗標相同,其所佔用的分布如下圖所示:

其中低位元的八個位元會受到算術、比較或邏輯運算的結果影響,而使旗標被設定(set,其值為1),或被清除(clear,其值為零)。較高的四個旗標是用來表示 CPU 的狀態。

第零位元是 CF (carry flag,進位旗標)表示進位或借位。如果加法有進位(80h+80h=100h),則此位元會被設為 1,當然減法乘法除法也是一樣,對減法來講就是借位。

第二位元 PF (parity flag,同位旗標)表示運算的結果換成二進位後,若有偶數個 1,則此位元設為 1,反之為 0。

第四位元是 AF (auxiliary carry flag,輔助進位旗標),是用於 BCD 運算中的進位。

第六位元是 ZF (zero flag,零旗標),運算結果為零時,此旗標會被設定為 1,若比較相同兩數, ZF 也會被設為一,若比較不相同的兩數,ZF 會被清除為零。

第七位元為 SF (sign flag,符號旗標),運算結果為負數,就是最高位元為 1 時,SF 會被設為 1,否則被清除。

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

第九位元為 IF (interrupt flag,中斷旗標),

第十位元為 DF (direction flag,方向旗標),當 DF 被清除時,處理字串的索引暫存器會遞增,往高位元組方向處理,反之則遞減。

第十一位元為 OF (overflow flag,溢位旗標),可以反映出運算結果是否超出有號數之範圍。

在此列出 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

白色的部分就是旗標的狀態,請看下表:

旗標名稱設定(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

8087 暫存器

8087 共有五類暫存器,它們是堆疊暫存器(register stack)、狀態字組(status word)、控制字組(control word)、標籤字組(tag word)、例外指標(exception pointer)。

1.堆疊暫存器

8087 共有八個堆疊暫存器,其名稱是 ST(0)、ST(1)、ST(2)……ST(7),其中 ST(0) 被稱為堆疊頂(TOS,Top Of Stack),在組合語言中也可簡寫成 ST。這八個堆疊暫存器每一個都有 80 位元的大小來存放浮點數,並且以暫時實數的形態存放,可以說相當的準確。有許多的運算都是會牽涉到 TOS ,有時也有 TOS 和其他堆疊暫存器做運算,所以 TOS 常常是可以省略,程式設計師得小心這種『隱含』的寫法,以免造成困擾。

2.狀態字組

顧名思義,這個暫存器是用來表示 8087 狀態的,其結構如下圖:

8087 狀態字組

它包含了四項資訊。

  1. 忙碌指示器(busy indicator):在第 15 位元,這個位元表示 8087 是否正在執行命令或運算,並沒太大的用處。

  2. 條件碼(condition code):在第 14、10、9、8 位元,以 C3、C2、C1、C0 表示,這幾個位元會受 FTST、FCOM、FXAM 等指令的影響,一般都是用來作為程式控制流程。

  3. 堆疊頂端指標:第 13、12、11 位元,這三個位元是用來指示現在的堆疊頂是那一個堆疊暫存器。

  4. 指示例外:第 7、5、4、3、2、1、0 位元,其作用如下表:

3.控制字組

這個 16 位元的暫存器決定了 8087 對不同例外條件的處理、如何捨入、控制實數精確度等等。控制字組的各個欄位如下圖所示:

8087 控制字組

對於控制字組說明如下:

  1. IEM (允許中斷遮罩):0 表示允許中斷,1 表示不允許中斷。

  2. PC (精確度控制):這是為了配合某些電腦廠商所製造較低精密度的機器而設的,其實在 8087 內部的堆疊暫存器都是以 80 位元的精密度存放資料。其表示方式是:
    00  表示 24 位元
    01  保留未使用
    10  表示 53 位元
    11  表示 64 位元   內定值
  3. RC (捨入控制):第 10、11 位元是用來決定如何做捨入動作的。
    RC捨入控制說明例子
    00四捨五入向最近的整數
    逢四捨去,遇五進位
    4.5 ==> 5
    -4.5 ==> -5
    01向負無限大捨入正值捨去小數部分
    負值捨去小數部分後再減一
    4.5 ==> 4
    -4.4 ==> -5
    10向正無限大捨入正值捨去小數部分後再加一
    負值捨去小數部分
    4.5 ==> 5
    -4.5 ==> -4
    11向零捨去不論正負值均捨去小數部分4.5 ==> 4
    -4.5 ==> -4


  4. IC (無限大控制):8087 有兩種方式可以對『無限大』與有限數作比較,一種是把正無限大與負無限大看成數線上的兩端,沒有數比正無限大還大,也沒有數比負無限大還小,這樣的方式下有限數是可以和正、負無限大比較。另一種是把正、負無限大看成同一點,相當於把數線繞合,這時有限數不可以和正、負無限大比較。前者稱『affine closure』,IC 設為 1;後者稱『projective closure』,IC 設為 0,這種方式也是 FINIT 後的內定值。

  5. 第 0 到第 5 位元分別是處理例外遮罩的方式,所謂例外是指 8087 運算時發生除以零、高過上限、低於下限、反常值、精確度這五種情形時,是否要讓 8088 知道。如果要讓 8088 知道稱之為『未遮罩』(unmasked) 此時該對應位元設為零,那麼如果發生例外時,可造成程式中斷而跳到設計者所設計的程式來處理。如果不使 8088 知道稱為『被遮罩』,對應位元設為一,當例外發生時 8087 能自動處理,因為 8087 對各種例外可說設計得相當不錯,因此內定值設為一。以下對這五種例外情形遮罩反應做說明:
    1. 除以零:ZM (zero-divide mask)位元設為零時,適當傳回正無限大或負無限大。
    2. 高過上限:OM (overflow mask)位元設為零時,適當傳回正無限大或負無限大。
    3. 低於下限:UM (underflow mask)位元設為零時,傳回反常結果。
    4. 反常值:DM (denormalized-operand mask)位元設為零時,記憶體運算原照常工作,堆疊暫存器變成異常值。
    5. 精確度:PM (precision mask)位元設為零時,傳回捨入結果。


標籤字組

8087 有一個 16 位元的標籤字組,標籤字組裏有八個標籤,每兩個位元為一個標籤,分別對應到八個堆疊暫存器。如下圖:

8087 的標籤字組

每個標籤代表相對應的堆疊暫存器內存入的數值形態。

  1. 00:可用數值,包含正常(normal)或異常值(unnormal)。
  2. 01:零。
  3. 10:非數值、無限大、反常值(denormal)。
  4. 11:空的。

8087 所能處理的數值資料形態,除了七種基本形態 (字組整數、短整數、長整數、短實數、長實數、暫時實數、聚集 BCD 整數) 之外,還保留了某些特殊的編碼方式來表示特殊的資料,這些特殊的資料一般應用上較少使用,在這兒簡單說明:

  1. 反常值(denormal):
  2. 異常值(unnormal):
  3. 零:
  4. 虛零(pseudo zero):
  5. 無限大:
  6. 實數未定值(real indefinit):
  7. 非數值(not a number):
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值