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

8086/8087寄存器(转载自小木偶)8086 暫存器暫存器是在 CPU 中一個暫時儲存資料的地方

大家好,欢迎来到IT知识分享网。

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/8087寄存器(转载自小木偶)

堆疊的部份,以獲得詳細的堆疊資料。堆疊是一塊區域,用來暫時存放資料之用,在 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 的旗標相同,其所佔用的分布如下圖所示:


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

其中低位元的八個位元會受到算術、比較或邏輯運算的結果影響,而使旗標被設定(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 狀態字組

它包含了四項資訊。

  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.控制字組


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):

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112729.html

(0)
上一篇 2026-01-16 14:00
下一篇 2026-01-16 14:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信