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