?? 匯011.txt
字號:
了解的內容:匯編語言對浮點數的定義和處理方法,它與高級語言中的浮點數相對應。
掌握的內容:在協處理器中,各類數據的存儲形式,用協處理器指令編寫浮點處理程序的方法。
考慮到不同學習的需要,本章內容可作為“選學”。
建議學習時間:8小時。
第11章 數值運算協處理器
數值運算協處理器(簡稱協處理器)是特為與微處理器協同工作而設計的,它是用于加速處理浮點數據的處理部件。對同樣的浮點計算,使用該部件進行運算所花的執行時間要比用常規指令編寫的最有效代碼所花的時間還要少得多。在早期的計算機系統中,該部件是可選部件,但現在一般都把協處理器直接內置在CPU之中。鑒于現在Pentium處理器內部結構的特點,該處理器能同時執行一條協處理器指令和二條整數指令。
協處理器的主要產品序列有:8087、80287、80387SX、80387DX和80487SX等。
協處理器可處理的數據類型有:16位、32位和64位有符號整數,18位BCD碼,32位、64位和80位浮點數。
協處理器可處理的運算有:乘法、除法、加法、減法、求平方根、部分正切、部分反正切和對數等運算。
11.1 協處理器的數據格式
在第4章,我們主要介紹了整數在內存中的存儲形式,這顯然不能滿足實際編程的需要。數據類型的另一大類就是浮點數,浮點數在內存中的存儲形式就是本節所介紹的主要內容。有關浮點數的存儲格式在《計算機組成原理》中的有關章節也有詳細說明,不太熟悉的讀者可進行輔助閱讀。
11.1.1 有符號整數
有符號數在協處理器中的應用與前面章節中所描述的方法是一致的,它是各種數據類型的基礎。這些整數可分為:16位(字型)、32位(短整型)和64位(長整型),其最高位為符號位。這些整數的數據格式如圖11.1所示,它們所能表示的數據范圍如表11.1所列。
(a) 字整型數據
(b) 短整型數據
(c) 長整型數據
圖11.1 有符號整型數據的數據格式
表11.1 各類整型數據的表示范圍
數據類型 范 圍
字型 -32768 ~ 32767
短整型 -2147483648 ~ 2147483647
長整型 -9×1018 ~ 9×1018
在匯編語言環境下,這三種整型數據的定義符分別為:DW、DD和DQ。如:
data1 DW 2, -340 ;16位整數
data2 DD 321, -320 ;短型整數
data3 DQ -1230, 9034 ;長型整數
11.1.2 BCD碼數據
一個BCD碼數據在內存中占80位,共10個字節。其最高位字節用來表示正負號,其余9個字節,每個字節內含有二個BCD碼,所以,一個BCD碼數據可表示18個BCD編碼。BCD碼的數據格式如圖11.2所示。
9 … 3 2 1 0
符號字節 … … BCD
BCD BCD BCD
圖11.2 BCD碼的數據格式
關于BCD碼的正負數,有如下規定:
、若最高位字節的值為0H,則表示該BCD碼的值為正數;
、若最高位字節的值為80H,則表示該BCD碼的值為負數。
在匯編語言環境下,BCD碼數據的定義符為:DT。如:
.387
BCD1 DT 1234, -340
該說明語句決定了數據在內存中的存儲形式如下:
00000000000000001234,80000000000000000340
11.1.3 浮點數
在計算機中,浮點數一般由三部分組成:數值的符號位、階碼和有效數字(以后簡稱為尾數)。這種浮點數是用科學記數法來表示的,即:浮點數=符號位.有效數字×2階碼。
Intel系列的協處理器支持3種形式的浮點數:短型浮點數(32位)、長型浮點數(64位)和臨時浮點數(80位),它們分別對應單精度、雙精度和擴展精度浮點數。這些浮點數的數據格式都符合IEEE-754標準,它們的具體格式如圖11.3所示。
圖11.3 80x87中浮點數的三種數據格式
一、十進制數轉換成浮點數的步驟
1、將十進制數轉換成二進制數:整數部分用2來除,小數部分用2來乘;
2、規格化二進制數:改變階碼,使小數點前面僅有第一位有效數字;
3、計算階碼:
◆ 短型浮點數的階碼加上偏移量7FH
◆ 長型浮點數的階碼加上偏移量3FFH
◆ 擴展型浮點數的階碼加上偏移量3FFFH
4、以浮點數據格式存儲。
把數值的符號位、階碼和尾數合在一起就得到了該數的浮點存儲形式。
注意:尾數是帶有一個隱含位的23位數,即:數“1.XXXX”的尾數是“XXXX”,前面的”1”被隱含掉,它只在擴展精度的格式中才被顯式表示出來。
例11.1 把十進制數100.25轉換成協處理器中的浮點數
解:
1、進制轉換:(100.25)10=(1100100.01)2
2、規格化:(1100100.01)2=1.10010001×26=1.10010001×2110
3、計算階碼:110+01111111=10000101
4、數值的符號位為0,階碼為:10000101,尾數為:1001 0001 0000 0000 0000 000
綜合上述可得:(100.25)10的浮點形式為:0 10000101 10010001000000000000000
下面是學習和掌握十進制數轉化為浮點數的控件,它可按步驟演示整個轉換過程。
幾個特殊數據的存儲規則:
正0: 所有的數據位都是0;
負0: 最高位為1,其它的數據位是0;
正/負無窮: 符號位為0/1,階碼位全為1,有效數字全為0;
NAN: 非法的浮點數,階碼位全為1,有效數字不全為0;
其中:NAN — Not-A-Number。
二、浮點數轉換成十進制數的步驟
該步驟與前面“十進制數轉換成浮點數”的步驟是互逆的,其具體步驟如下:
1、分割數字的符號、階碼和有效數字;
2、將偏移階碼減去偏移,得到真正的階碼;
3、把數字寫成規格化的二進制數形式;
4、把規格化的二進制數改變成非規格化的二進制數;
5、把非規格化的二進制數轉換成十進制數。
例11.2 把協處理器中的浮點數1100000111001001000000000000轉換成十進制數
解
1、把浮點數1100000111001001000000000000分割成三部分,可得:
符號位是1,階碼是10000011,尾數是1001001000000000000
2、還原階碼:10000011 – 01111111=100
3、該浮點數的規格化形式:1.1001001×24 (其中前面的“1.”從隱含位而來)
4、該浮點數的非規格化形式:11001.001
5、該浮點數的十進制數為-25.125 (因為符號位為1,所以,該數是負數)
下面是學習和掌握十進制數轉化為浮點數的控件,它可按步驟演示整個轉換過程。
三、浮點數說明形式
在匯編語言中,可用DD、DQ和DT來分別說明單精度、雙精度和擴展精度的浮點數。
在MASM 6.0系統中,正浮點數前面不能書寫‘+’,但MASM 6.11系統更正了這種錯誤,并提供了新的浮點數說明方法,即:可用REAL4、REAL8和REAL10來分別代替DD、DQ和DT。
在定義浮點數時,要使用偽指令.8087、.287或.387等。
例如:
.387
data1
DD
123, -543
;定義單精度浮點數
data2
REAL4
3.345E+3
;定義單精度浮點數
data3
REAL8
321.545
;定義雙精度浮點數
data4
REAL10
254.555
;定義擴展精度浮點數
11.2 協處理器的結構
協處理器,顧名思義,是為與CPU協同工作而設計的,其主要用來提高進行數學和超越函數計算的速度。在80486DX和Pentium處理器中都內置一個與80387完全兼容的協處理器。CPU執行所有的常規指令,協處理器則執行協處理器指令,它們能同時并行地執行各自的指令。由于現在Pentium處理器內部結構的特點,該處理器能同時執行一條協處理器指令和二條整數指令。
11.2.1 協處理器的內部結構
協處理器80x87的內部結構如圖11.4所示。它可分為二個主要部分:控制部件(CU)和數值執行部件(NEU)。
圖11.4 80x87的內部結構示意圖
控制部件(CU)把協處理器接到CPU的系統總線上,協處理器和CPU都監視正在執行的指令流。如果當前將要執行的指令是協處理器指令(即:ESCape指令),那么,協處理器會自動執行它,否則,該指令將交給CPU來執行。
數值執行部件(NEU)復制執行所有的協處理器指令,它有一個用8個80位的寄存器組成的堆棧,該堆棧用于以擴展精度的浮點數據格式來存放數學指令的操作數和運算結果。在協處理器指令的執行過程中,要么指定該堆棧寄存器中的數據,要么使用壓棧/出棧機制來從棧頂存放或讀取數據。
在NEU部件中,還有一些記錄協處理器工作狀態的寄存器,如:狀態寄存器、控制寄存器、標記寄存器和異常指針寄存器等。有關這些寄存器的作用將在后面給予分別介紹。
11.2.2 狀態寄存器
狀態寄存器是用來標識協處理器中指令執行情況的,它相當于CPU中的標志位寄存器。80x87協處理器的狀態寄存器如圖11.5所示。
15 13 12 11 8 7 0
B
C3
TOP C2 C1 C0 ES SF PE UE OE ZE DE IE
圖11.5 80x87協處理器的狀態寄存器示意圖
狀態寄存器各標志位(或組合位)的含義如下:
◆ B(Busy,忙)
忙標志位用來表明協處理器是否正在執行協處理器指令,它可用FWAIT指令來測試。在80287及其以后的協處理器中,協處理器和CPU能自動實現同步,所以,現在在運行任務時,無須測試忙標志。
◆ C3~C0(條件編碼位)
四位條件編碼位的組合含義如表11.2所列。
表11.2 狀態寄存器中條件編碼位的組合含義
指 令
C3 C2 C1 C0 功 能
FTST、FCOM 0 0 X 0 ST>操作數或(0 FTST)
0 0 X 1 ST<操作數或(0 FTST)
1 0 X 0 ST=操作數或(0 FTST)
1 1 X 1 ST不可比較
FPREM Q1 0 Q0 Q2 Q2Q1Q0是商的右邊3位
? 1 ? ? 未完成
FXAM 0 0 0 0 +unnormal
0 0 0 1 +NAN
0 0 1 0 -unnormal
0 0 1 1 -NAN
0 1 0 0 +normal
0 1 0 1 +∞
0 1 1 0 -unnormal
0 1 1 1 -∞
1 0 0 0 +0
1 0 0 1 空
1 0 1 0 -0
1 0 1 1 空
1 1 0 0 +denormal
1 1 0 1 空
1 1 1 0 -denormal
1 1 1 1 空
其中,normal—標準的浮點數,unnormal—有效數字前面是0,如:0.XXXX,denormal—階碼是最大的負值,NAN—見11.1.3節中幾個特殊數據的說明。
◆ TOP(棧頂)
該三位二進制000~111用來表明當前作為棧頂的寄存器,通常其值為000。
◆ ES(錯誤匯總)
ES=PE+UE+OE+ZE+DE+IE(邏輯或運算),在8087協處理器中,當ES為1時,將發出一個協處理器中斷請求,但在其后的協處理器中,不再產生這樣的協處理器中斷申請。
◆ SF(堆棧溢出錯誤)
該狀態位用來表明協處理器內部的堆棧是否有上溢或下溢錯誤。
◆ PE(精度錯誤)
該狀態位用來表明運算結果或操作數是否超過先前設定的精度。
◆ UE(下溢錯誤)
該狀態位用來表明一個非0的結果太小,不能用控制字節所選定的當前精度來表示。
◆ OE(上溢錯誤)
該狀態位用來表明一個非0的結果太大,不能用控制字節所選定的當前精度來表示,即超過了當前精度所能表示的數據范圍。
如果在控制寄存器中屏蔽該錯誤標志,即設控制寄存器中的OM為1,那么,協處理器把上溢結果定義為無窮大。
◆ ZE(除法錯誤)
該狀態位用來表明當前執行了“0作除數”的除法運算。
◆ DE(非規格化錯誤)
該狀態位用來表明當前參與運算的操作數中至少有一個操作數是沒有規格化的。
◆ IE(非法錯誤)
該狀態位用來表明執行了一個錯誤的操作,如:求負數的平方根,也可用來表明堆棧的溢出錯誤、不確定的格式(0/0,∞,-∞等)錯誤,或用NAN作為操作數。
對于協處理器中狀態寄存器的內容,程序員可用指令FSTSW把其值送到內存單元中。如果當前使用的是80287及其以后的協處理器,那么,可用指令“FSTSW AX”把該狀態寄存器的值傳送給通用寄存器AX。一旦狀態寄存器的值復制到內存或AX中,那么,就可對其各位進行分析,并可檢測出當前協處理器的工作狀態。
對于80287協處理器,它還可通過I/O地址00FAH~00FFH來實現其與CPU之間的數據交換,而80387~Pentium系列芯片,則是通過I/O地址800000FAH~800000FFH來實現這兩者之間的數據交換。
當狀態寄存器的內容傳給AX之后,一般可用下面二種方法來檢測協處理器的狀態。
方法1:用TEST指令來檢測其相應的狀態位。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -