彙編,浮點運算符,fldpi,fmul等指令說明.

協處理器指令系統編程

 

協處理器共有68條不一樣的指令,彙編程序在遇到協處理器指令助記符時,都會將其轉換成機器語言的ESC指令,ESC指令表明了協處理器的操做碼。安全

協處理器指令在執行過程當中,須要訪問內存單元時,CPU會爲其造成內存地址。協處理器在指令執行期間內利用數據總線來傳遞數據。80287協處理器利用I/O地址00FAH~00FFH來實現其與CPU之間的數據交換,而80387~Pentium系列芯片,則是利用I/O地址800000FAH~800000FFH來實現這二者之間的數據交換。函數

 

一.指令操做符的命名規則spa

協處理器指令的操做符(或助憶符)在命名設計時,遵循了下列規則:設計

一、在操做符後面加上字母P:表示該指令執行完後,還進行一次堆棧彈出操做,彈出棧頂數據之後要對其它的寄存器進行相應的調整。如:FADDP/FSUBP/FSUBRP /FMULP/FDIVP /FDIVRP等;指針

二、在操做符後面加上字母R:表示將兩個操做數的源/目的位置交換再進行運算,它僅限於減法、除法指令,由於加法和乘法不受源/目的操做數的位置影響結果。如:FSUBR和FDIVR等;對象

不加R時 —— 目的操做數=目的操做數 op 源操做數
加R模式 —— 目的操做數=源操做數 op 目的操做數內存

假設:棧頂數據st(0)爲10,內存變量data的值爲1,分別執行下列指令將有不一樣的結果。ci

                  FSUB                      data ;     ST(0)=ST(0)-data數學

                  FSUBR                   data ;ST(0)=data-ST(0)

                  FSUB                      ST(3), ST(0)    ;指令執行後,ST(3)=ST(3)-ST(0)

                  FSUBR                   ST(3), ST(0)    ;指令執行後,ST(3)=ST(0)-ST(3)

三、操做符的第2個字母是I:表示內存操做數是整數(注意:不能是BYTE類型)。它對加、減、乘、除指令以及堆棧操做指令都有效。

FIADD data —— 整數加法,它表示內存單元data是一個整數,把該整數加到棧頂的浮點數上(ST(0)=ST(0)+data)。

四、操做符的第二個字母是B:表示用於操做壓縮的BCD碼格式的內存操做數(用TWORD聲明,10個字節),如FBLD和FBSTP等。

五、操做符的第2個字母是N:表示在指令執行以前檢查非屏蔽數值性錯誤。如:FSAVE和FNSAVE等,前者稱爲等待形式(wait version),後者稱爲非等待形式(no-wait version)。

在使用.8087僞指令狀況下,彙編程序會在等待形式的指令前面加上指令WAIT,而在非等待形式的指令前面加上空操做指令NOP。

理解了上述操做符命名規則,就能很容易地區分同類指令之間的差別。

 

二.數據傳送指令

爲了知足協處理器和CPU之間進行數據交流的需求,就須要實現內存單元和協處理器之間進行數據傳送的指令。協處理器的指令系統中有三大類數據傳送指令:BCD傳送指令、數傳送指令和浮點數傳送指令。

(一)、BCD傳送指令

一、FBLD

指令格式:FBLD MemBCD
指令功能:將操做數中的BCD數據壓入協處理器的堆棧中(ST(0)=MemBCD);MemBCD是TWORD類型的內存變量。

二、FBSTP

指令格式:FBSTP MemBCD
指令功能:將協處理器中的BCD數據存入內存(MemBCD=ST(0)),並進行堆棧的彈出操做。

例如:

      .387

                data1    DT 123, -543

                data2    DT 2.5

      ……

                FBLD                    data1

                FBSTP                  data

 

 

 

 

                ;把data1壓進棧(ST(0)=data1)

                ;把當前堆頂數據彈出,並傳送給data (data=ST(0))

 

(二)、整數傳送指令

一、FILD

指令格式:FILD MemInt             ;ST(0)=MemInt

其中:MemInt是定義爲整型數據類型的內存單元,但不能是用BYTE定義的存儲單元。下同,再也不敘述。

二、FIST/FISTP

 

指令格式:

 

其中:

 

指令功能:

FIST MemInt
FISTP MemInt

Mem是定義整型數據類型的內存單元,(用WORD,DWORD和QWORD定義)。

將協處理器堆棧棧頂的數據傳送到目標存儲單元中。在進行數據傳送時,系統自動根據控制寄存器中舍入控制位的設置把棧頂浮點數舍入成整型數據。

而FIST與FISTP的區別在之前就講過,在執令後加P的表示帶有出棧操做。那麼FIST的功能是MemInt=ST(0),但ST(0)不出棧,但FISTP則在進行傳送以後再進行對棧頂進行出棧。

 

(三)、浮點數傳送指令

一、FLD

指令格式:

FLD STReg/MemReal

指令功能:

將浮點數據壓入協處理器的堆棧中。當進行內存單元內容壓棧時,系統會自動決定傳送數據的精度。好比:用DD或REAL4定義的內存單元數值是單精度數等。

STReg是處理器堆棧寄存器ST(0)~ST(7)。

例如:

 

.387

data1  DWORD 123, -543

data2  REAL8 -321.5

data3  REAL10 2.5

……

FLD  data1  ;壓一個單精度數據進棧

FLD  data2  ;壓一個雙精度數據進棧

FLD  ST(0)  ;把堆棧寄存器ST(0)的值再壓進棧

FLD  data3  ;壓一個擴展精度數據進棧

二、FST

 

指令格式:

指令功能:

FST  STReg/MemReal

將協處理器堆棧棧頂的數據傳送到目標操做數中。在進行數據傳送時,系統自動根據控制寄存器中舍入控制位的設置把棧頂浮點數舍入成相應精度的數據。

三、FSTP

 

指令格式:

FSTP  STReg/MemReal

指令功能:

與FST相相似,所不一樣的是:指令FST執行完後,不進行堆棧的彈出操做,即:堆棧不發生變化,而指令FSTP執行完後,則須要進行堆棧的彈出操做,堆棧將發生變化。

從上面的浮點傳送指令中能夠看出,不只能夠對內存變量進行傳送,也能夠進行寄存器之間的傳送,這一點是整型數據以及BCD型數據傳送指令所不具備的。

四、FXCH

 

指令格式:

指令功能:

FXCH [STReg]

將指定的寄存器中的浮點數與堆頂浮點數進行交換。若是不指定操做數,那麼,默認ST(0)和ST(1)兩者之間交換數據。

例如:FXCH  ST(2)  ——  ST(0)與堆棧寄存器ST(2)進行數據交換。

因爲FXCH指令隱含ST(0)做爲其中的一個操做數,因此其後只需指定一個操做數,但該操做數必須是寄存器,並且不能爲ST(0),可是該指令後的寄存器是可選的,若是沒有指定寄存器操做數,那麼隱含是對ST(1)和ST(0)進行交換。

對數據傳送指令的一點總結:它包括三種數據的傳送指令,整型,壓縮的BCD型以及實型,三種數據的傳送有各自的指令集。

壓縮的BCD傳送指令僅有壓棧以及彈棧兩條:FBLD以及FBSTP,它們都僅有一個操做數,並且操做數必須是內存操做數的TWORD類型。

整型數據傳送指令有三條:FILD、FIST和FISTP,其中後兩條是出棧,惟一的區別在於出棧後是否改變(彈出)棧頂數據。它們都僅有一個操做數,並且操做數必須是內存操做數的WORD、DWORD以及QWORD類型,不能爲BYTE類型。

相對來說,實數傳送指令比較多,它一共有四條:FLD、FST、FSTP和FXCH。前三條指令的用法與整型相似,只不過用於傳送實型數據,並且三條指令不只支持內存操做數(爲REAL四、REAL8和REAL10類型),並且支持寄存器之間的傳送。三條指令一樣須要一個操做數。而對於FXCH指令,它能夠有一個或者沒有操做數,但若是有操做數,那麼這個參數必須爲寄存器。

 

三.算術運算指令

在協處理器的指令系統中,有關數學運算指令有:加法指令、減法指令、乘法指令、除法指令和求平方根指令等。涉及數學運算的指令有比例運算、舍入運算、求絕對值運算和改變數值符號運算等指令。

(一)、整型算術運算指令

指令格式:

FIADD  MemInt              ;加法指令

FISUB  MemInt              ;減法指令

FISUBR  MemInt             ;減法指令

FIMUL  MemInt              ;乘法指令

FIDIV  MemInt               ;除法指令

FIDIVR  MemInt              ;除法指令

指令說明:

因爲整型算術運算指令都僅有一個操做數,那麼另外一個操做數就被隱含成ST(0),而運算結果也被保存在ST(0)中。

加和乘都僅有一條指令,它們的運算規則爲:

ST(0)=ST(0)+MemInt

ST(0)=ST(0)*MemInt

但減法和除法都分別有兩條指令,後面帶R的指令是在運算以前先交換源/目的操做數的位置再進行運算。因爲在加法和乘法運算中交換兩個操做數的位置的運算結果是同樣的,因此不存在加R的狀況。

減法和除法的運算規則爲:

ST(0)=ST(0)-MemInt              ;相對於FISUB指令。

ST(0)=MemInt-ST(0)              ;相對於FISUBR指令。

ST(0)=ST(0)/MemInt              ;相對於FIDIV指令。

ST(0)=MemInt/ST(0)              ;相對於FIDIVR指令。

綜上所述,在進行整型算術運算中,僅須指定一個內存操做數就能夠了,另外一個操做數則默認爲是ST(0),而且結果也存放在ST(0)中。

(二)、實型算術運算指令

1.不帶彈出操做的算術運算指令。

指令格式:

FADD  [STReg1, STReg2]            ;加法指令。

FADD  MemReal                   ;加法指令。

FSUB  [STReg1, STReg2]            ;減法指令

FSUB  MemReal                    ;減法指令

FSUBR  [STReg1, STReg2]           ;減法指令

FSUBR  MemReal                   ;減法指令

FMUL  [STReg1, STReg2]            ;乘法指令

FMUL  MemReal                    ;乘法指令

FDIV  [STReg1, STReg2]             ;除法指令

FDIV  MemReal                     ;除法指令

FDIVR  [STReg1, STReg2]            ;除法指令

FDIVR  MemReal                    ;除法指令

上面的指令能夠分爲帶R和不帶R,區別在之前就講過。從上面的格式能夠看出,它們都有三種使用格式:

(1) 不帶任何操做數。

若是不帶操做數,那麼FPU就默認爲ST(1)做爲目的操做數,而ST(0)做爲源操做數。但這種狀況下有一個彈出的動做,如:

.DATA

Val1   REAL8           3.14

Val2   REAL8           4.13

.CODE

         FLD Val1  ;ST(0)=3.14

         FLD Val2  ;ST(0)=4.13    ST(1)=3.14

         FSUB   ;ST(1)=ST(1)-ST(0)=3.14-4.13=-0.99,再彈出ST(0)

也就是說執行過程是ST(1)=ST(1) op ST(0),再將ST(0)彈出,那麼ST(1)就變成ST(0),而原來的ST(0)就被彈出了。這一點是初學者最容易忘記的地方,在不帶有P的算術運算指令進行實數運算,而且不指定任何操做數的時候,指令默認有一個彈出操做。但這個規則僅用於實型算術運算,由於整型算術運算有一個操做數。

(2) 帶有一個操做數。

從上面的指令格式能夠看出,若是帶有一個操做數,那麼這個操做數必須是內存操做數,在這種狀況下,將ST(0)與該操做數進行運算,無論源/目的操做數位置如何,結果都存入ST(0)中(注意:這種狀況沒有彈出動做)。例如:

.DATA

Val1   REAL8           3.14

Val2   REAL8           4.13

.CODE

         FLD Val1  ;ST(0)=3.14

         FSUB Val2  ;ST(0)=ST(0)-Val2=3.14-4.13=-0.99

而在上面的FSUB帶一個R的話,即

    FSUBR Val2

那麼就進行ST(0)=Val2-ST(0)的運算。

(3) 帶兩個操做數。

若是帶有兩個操做數,那麼兩個操做數必須都爲寄存器,並且其中一個寄存器必須爲ST(0)。結果存入目的寄存器中,一樣這種狀況不帶彈出動做。例如:

.DATA

Val1   REAL8           3.14

Val2   REAL8           4.13

.CODE

         FLD Val1  ;ST(0)=3.14

         FLD Val2  ;ST(0)=4.13  ,ST(1)=3.14

         FSUB  ST(0),ST(1)

那麼,ST(0)=ST(0)-ST(1)=4.13-3.14=0.99,但ST(1)的值不變,仍是爲3.14。若是寫成:

          FSUB  ST(1),ST(0)

那麼,ST(1)=ST(1)-ST(0)=3.14-4.13=-0.99,而ST(0)值不變。

2.帶彈出操做的算術運算指令

指令格式:

FADDP  STReg, ST                  ;加法指令

FSUBP  STReg, ST                  ;減法指令

FSUBRP  STReg,ST                 ;減法指令

FMULP  STReg, ST                 ;乘法指令

FDIVP  STReg, ST                  ;除法指令

FDIVRP  STReg, ST                 ;除法指令

因爲全部的指令都帶P,那麼都有彈出動做,從指令格式中能夠看出,它們都有兩個操做數,並且倆操做數都是寄存器,源操做數都是ST(0)寄存器,而目的操做數是ST(1)~ST(7)中的任何一個,但不能是ST(0)。在進行運算時,運算結果存入目的寄存器中(ST(1)~ST(7)),而後對ST(0)進行彈出,彈出後下面的全部寄存器都要做相應的調整,例如:

.DATA

Val1   REAL8           3.14

Val2   REAL8           4.13

.CODE

         FLD Val1  ;ST(0)=3.14

         FLD Val2  ;ST(0)=4.13   ST(1)=3.14

         FSUBRP   ST(1),ST(0)

那麼,結果是這樣計算的:ST(1)=ST(0)-ST(1)=4.13-3.14=0.99而且將ST(0)彈出,而後存放結果的ST(1)以及後續的寄存器就進行調整,那麼此時ST(1)就變成ST(0)了,那麼最後的結果存入ST(0)中,而原來的ST(0)值4.13則被移出。

(三)、其它數學運算指令

在協處理器中,除了完成具體的數學運算指令外,還設置了若干個與數學運算有關的運算指令。

改變符號:FCHS

這個指令會改變 ST(0)的正負值,若是原先 ST(0)爲正值,執行後變爲負值;原先爲負值,執行後爲正值。能夠用這個指令計算相反數。

絕對值:FABS

把 ST(0)之值取出,取其絕對值後再存回去。

平方根:FSQRT

將 ST(0)之值取出,開根號後再存回去。

FSCALE 指令

這個指令是計算ST(0)*2ST(1)之值,再把結果存入 ST(0) 裏而 ST(1) 之值不變。ST(1) 必須是在 -32768 到 32768 (-215 到 215 )之間的整數,若是超過這個範圍計算結果沒法肯定,若是不是整數 ST(1) 會先向零舍入成整數再計算。因此爲安全起見,最好是由整數載入到 ST(1) 裏。

FRNDINT 指令

這個指令是把 ST(0) 的數值舍入成整數,FPU 提供四種舍入方式,由 FPU 的控制字組(control word)中的 RC 兩個位決定,以下表:

RC

舍入控制

說明

例子

00

四捨五入

向最近的整數
逢四捨去,遇五進位

4.8 → 5.0  -4.8 →-5.0
4.2 → 4.0  -4.2 →-4.0

01

取小於源數的最大整數

正值捨去小數部分
負值捨去小數部分後再減一

4.8 → 4.0  -4.8 →-5.0
4.2 → 4.0  -4.2 →-5.0

10

取大於源數的最小整數

正值捨去小數部分後再加一
負值捨去小數部分

4.8 → 5.0  -4.8 →-4.0
4.2 → 5.0  -4.2 →-4.0

11

向零對齊

不論正負值均捨去小數部分

4.8 → 4.0  -4.8 →-4.0
4.2 → 4.0  -4.2 →-4.0

FPREM 指令

這個指令是求餘數,較簡略的說法是將 ST(0) 除以 ST(1) 後的餘數存回 ST,ST(1) 則不變(ST(0)=ST(0)%ST(1))。這個指令實際運做時,是以連續減法的方式求出餘數。

FXTRACT 指令

這個指令稱爲抽取指數與有效數,是把 ST(0) 內的數值改爲 X*2Y,而後把 Y 存回 ST(0)裏,再把 X 壓入堆棧,因此最後 ST(0)爲有效數,ST(1) 爲以 2 爲底的指數。FXTRACT 與 FSCALE 剛好成相反運算。

 

.比較運算指令

使用比較指令是將棧頂中的數(ST(0))與其它操做數進行比較,實現條件跳轉。所謂條件跳轉就是比較兩數的大小,若是某數較大,就執行一段程序,若較小則執行另外一段程序。在 FPU 的指令集並無能使 FPU 跳轉的指令,事實上 FPU 也沒法改變 CPU 寄存器之值 (還記得要改變程序執行地址必須改變 CS:IP 之值),因此要產生 FPU 條件跳轉必須用間接方法。其步驟有四個:

先用 FPU 的比較指令改變 FPU 的狀態寄存器寄存器。

再用 FPU 的指令 FSTSW 把狀態寄存器存入一個內存變量裏。

將此內存變量存入 AH 寄存器,再用 CPU 指令 SAHF 指令存入 CPU 的標誌寄存器裏。此步驟使標誌寄存器之值等於FPU狀態寄存器。

再用 CPU 指令 JL/JG/JE/JA/JB 來跳轉至正確處執行。

狀態寄存器

FPU 有五類寄存器,前章已介紹過最經常使用的堆棧寄存器,這裏將介紹狀態寄存器(status register)。狀態寄存器是一個 16 位的寄存器,表示 FPU 的狀態,所謂狀態是指 FPU 是否是在忙碌中、是否除以零、是否無效運算、如今堆棧頂端是那一個堆棧寄存器等等,在此處咱們要注意的是四個狀態碼位,C0、C一、C二、C3。這些位分佈以下圖:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

 

B

C3

TOP

C2

C1

C0

ES

SF

PE

UE

OE

ZE

DE

IE

 

比較指令:FCOM、FCOMP、FCOMPP、FICOM、FICOMP

標題所見的這些比較指令都是以堆棧頂(ST(0))爲目的操做數,而源操做數能夠是內存變量或是其它的堆棧寄存器,例如:

FCOM    ST(0),ST(1)

FCOM    ST(0),x

上述第一例是比較 ST(0)和ST(1) 之數值,第二例是比較 ST(0)和內存變量 x 之數值,而這內存變量的形態能夠是短實數和長實數。由於 FCOM 等指令均以 ST(0)爲目的操做數,因此 ST(0)是能夠省略不寫的,例如上述兩例,能夠寫成下面的樣子,

FCOM    ST(1)

FCOM    x

結果是同樣的。假如 ST(0)的比較對象是 ST(1) 的話(源操做數是ST(1)),連 ST(1) 也能夠省略。至於 FCOMP 和 FCOMPP 分別是比較後彈出一次和彈出兩次,這裏彈出的數會丟失而不會存入內存中,這點和 FSTP 不一樣。而 FICOM 和 FICOMP 是用來比較整數的,而源操做數能夠是字和雙字整數,但不能是寄存器,至於目的操做數默認爲是ST(0)。

FPU 的比較指令會改變狀態寄存器的 C3 和 C0 位,比較後跟據ST(0)和源操做數的大小,設置C3 和 C0標誌位以下表所示:

比較結果

C3

C0

ST(0)>源操做數

0

0

ST(0)<源操做數

0

1

ST(0)=源操做數

1

0

ST(0)不可比較

1

1

 

FSTSW 指令

FSTSW (store status register) 這個指令的功能是把狀態寄存器取出並存入內存變量裏,而這個內存變量必須是 16 位的內存變量。其語法是:

FSTSW   mem16

SAHF 指令

SAHF 是 8088 指令集中的一個指令,並不是 FPU 指令。這個指令是把 AH 寄存器中的值移到標誌寄存器的較低的 8 個位,這 8 個位只有第7、6、4、2、零位有用,第5、3、一位沒有使用。以下圖所示:

 

因此假如 AH 爲 0100 0000B,則執行 SAHF 指令後,零標誌會被設爲一。因此,跳轉指令實際上是僅僅看標誌寄存器的設定值決定如何跳轉,至於標誌寄存器如何設定(人爲仍是機器指令運行結果),在跳轉指令執行時是不會理會的。

FPU 的狀態寄存器裏的 C3 和 C0 位,經 FSTSW 指令傳到 16 位內存變量,再傳到 AX 寄存器裏,AH 的第 6和0 位(ZF和CF)就是表示 C3 和 C0 位,再由 SAHF 指令移到標誌寄存器,其對應的位是零標誌與進位標誌,因此只要檢查這兩個標誌就能夠比較 ST(0)與源操做數的大小,而決定跳轉方向。

FTST和FXAM指令

FTST  棧頂數據ST(0)與0進行比較。

FXAM  檢測棧頂數據ST(0)是正數、負數,仍是規格化數。

兩條指令都是無操做數指令,它們的的比較結果參考C3和C0值的那個表。

 

.常數操做指令

FPU 裏有 7 個指令是用來把經常使用的常數壓入堆棧頂稱爲常數指令。這些常數都是內建在 FPU 裏的數值,都屬於暫時實數,其有效位數達 19 位數,當程序須要用到時能夠很快的加載,節省時間與內存。這 7 個常數指令介紹以下:

FLD1      載入 1.0。( 把 1.0 壓入堆棧頂 )

FLDZ      載入零。( 把 0.0 壓入堆棧頂 )

FLDPI     載入圓周率,3.141592653589793239。( 把 π 壓入堆棧頂 )

FLDL2T    載入Log210。(把 Log210壓入堆棧頂)

FLDL2E    載入Log2e,e 是天然對數的底數。( 把Log2e壓入堆棧頂 )

FLDLG2    載入Log102。( 把Log102壓入堆棧頂 )

FLDLN2    載入Loge2,事實上Loge2等於 Ln 2。( 把Loge2壓入堆棧頂 )

 

.超越函數運算指令

所謂超越函數運算指令是指複雜的函數運算的指令。8087 有五個超越指令,一個用於指數,兩個用於天然對數,另外兩個用於三角函數的計算。對於 8087 的超越指令所輸入的自變量和數學上的自變量不徹底相同,例如求 2 的 X 次方,在數學上 X 能夠是任意值,但用 8087 計算時 X 卻只能在 0 到 0.5 之間,若是要求 2 的任意數次方得用程序來計算。假如在 8087 程序中的自變量超過這個範圍,會引發錯誤可是 8087 卻沒有檢查機制,因此要當心使用。

F2XM1 指令

這個指令是用來計算2ST-1而後將結果存回 ST 裏。F2XM1 裏的 X 表示 ST 寄存器,M 表示減法之意,它的語法就是:

F2XM1

不含任何操做數。這個指令運算以前還有一個限制,那就是 X 必須是在 0 到 0.5 之間的實數才行,能夠等於 0 或 0.5;在 Pentium 等級及其以上,X 能夠擴充到在 0 到 1 之間。這個指令之因此要減一的目的是若是 X 很小,則2X會很接近一,減去一可增長有效數。

FYL2X 指令

這個指令是用來計算ST(1)*Log2 ST,這個指令會先彈出 ST 而後以計算的結果取代 ST 寄存器。這個指令的限制是 ST 必須爲正數。

FYL2XP1 指令

這個指令是計算ST*Log2( ST(1)+1 ),這個指令會先彈出 ST 而後以計算的結果取代 ST 寄存器,ST(1) 必須是大於零且小於二分之根號二的數。這個指令在 Log 後的數很接近一時,比 FYL2X 有較好的準確度。

FPTAN 指令

這個指令用來計算 tan(ST) 之結果,而計算結果是以分數 Y/X 的形式存入堆棧,計算後先把 tan(ST)之值壓入堆棧(看成 Y 值),再把 1 (看成 X 值)壓入堆棧,換句話說最後的結果是ST(1)爲tan(ST),ST爲1。在8087等級的FPU運算時,計算前ST必須是0~π/4;若是在 Pentium 等級及其以上的 CPU,除了計算前ST須以弧度表示外,彷佛沒有範圍限制。

FPATAN 指令

這個指令是用來計算 arctan ( ST(1)/ST ) 的,而後把計算結果以弧度表示存入ST。整個計算過程是先彈出堆棧頂當作分母(X),再彈出新的堆棧頂(也就是原來的ST(1) )當作分子,計算Y/X之反正切函數,再把計算結果存回堆棧頂。若是是在 8087 FPU 上運算,計算前 ST 與 ST(1) 必須爲正值,而在 Pentium 及其以上的 CPU 則無此限制。

在 80387 等級及其以上的 FPU 還提供的更多的超越函數:

FSIN 指令

這是用來計算堆棧頂的正弦函數 (sin),再把結果壓入堆棧頂,計算前堆棧頂沒有範圍的限制,但要使用弧度,80387 等級及其以上的 FPU 才提供這個指令。

FCOS 指令

這是用來計算堆棧頂的餘弦函數 (cos),再把結果壓入堆棧頂,計算前堆棧頂沒有範圍的限制,但要使用弧度,80387 等級及其以上的 FPU 才提供這個指令。

FSINCOS 指令

這個指令只有在 80387 等級及其以上的 FPU 才提供,它會彈出堆棧頂而後計算 sin ST 與 cos ST 之值,而後把 sin ST 之結果壓入堆棧寄存器,再把 con ST 之結果壓入堆棧寄存器,因此堆棧頂爲餘弦值, ST(1) 爲正弦值。

 

.協處理器控制指令

協處理器控制指令是用來控制協處理器狀態而設置的,它包括協處理器的初始化狀態寄存器內容的存取異常處理任務切換等操做。

FINIT/FNINIT 

初始化協處理器,初始化後協處理器的狀態以下表所示:

協處理器初始化的狀態

控制項

狀態含義

控制位IC

0

投影

控制位PC

10

擴展精度

控制位RC

00

最近舍入或偶數

錯誤屏蔽

11111

錯誤位關閉

忙標誌

0

不忙

C3~C0

????

未定

TOP

000

堆棧棧頂設定爲寄存器0

ES

0

無錯誤

錯誤位

00000

無錯誤

所有標記

11

寄存器

--

不改變

 

FLDCW Mem16

將由操做數指定的字存儲單元內容存儲到控制寄存器中。

FSTCW/ FNSTCW Mem16

把控制寄存器的內容存儲到由操做數指定的字存儲單元。與指令「FLDCW」相對應。

FSTSW Mem16

FSTSW AX

FNSTSW Mem16

FNSTSW AX

將控制寄存器的內容傳送到寄存器AX中。在8087協處理器中無此指令。

FCLEX/FNCLEX

清除狀態寄存器中的「錯誤」和「忙」標誌。

FSAVE Mem

FNSAVE Mem

將所有機器狀態存儲到內存中。

FRSTOR Mem

從內存復原機器狀態,它可恢復由指令「FSAVE/FNSAVE」保存的信息。

FSTENV Mem

FNSTENVMem

存儲協處理器環境。

FLDENV Mem

從新裝入由指令FSTENV/FNSTENV存儲的協處理器環境。

FINCST

堆棧指針加1。

FDECSTP

堆棧指針減1。

FFREE ST(i)

釋放堆棧寄存器,即便其標記爲空,但其內容並無改變。

FNOP

協處理器的空操做

FWAIT

使處理器處於等待狀態,以便協處理器完成其操做。該指令主要用於在CPU訪問被協處理器影響的內存數據以前。

相關文章
相關標籤/搜索