Assembly 數(shù)字協(xié)處理器

2018-11-01 11:21 更新

硬件

早期的Intel處理器并沒(méi)有提供支持浮點(diǎn)操作的硬件。這并不意味著它們不可以執(zhí)行浮點(diǎn)操作。它僅僅表示它們需要通過(guò)由許多非浮點(diǎn)指令組成的程序來(lái)執(zhí)行這些操作。對(duì)于早期的系統(tǒng),Intel提供了一片額外的稱(chēng)為數(shù)學(xué)協(xié)處理器的芯片。相比于使用軟件程序,數(shù)學(xué)協(xié)處理器擁有能快速執(zhí)行許多浮點(diǎn)操作的機(jī)器指令(在早期的處理器上,至少快10倍!)。8086/8088的協(xié)處理器為8087。80286的協(xié)處理器為80287,80386的為80387。80486DX處理器將數(shù)學(xué)協(xié)處理器內(nèi)置到80486中了。從Pentium開(kāi)始,所有生產(chǎn)的80x86
處理器都內(nèi)置數(shù)學(xué)協(xié)處理器;但是,它依然被規(guī)劃成好像它是一個(gè)分離的單元。即使是早期沒(méi)有協(xié)處理器的系統(tǒng)都可以安裝一個(gè)模擬數(shù)學(xué)協(xié)處理器的軟件。當(dāng)一個(gè)程序執(zhí)行了一條協(xié)處理器指令時(shí),這個(gè)模擬軟件包將自動(dòng)激活并執(zhí)行一個(gè)軟件程序來(lái)得到與真實(shí)協(xié)處理器一樣的結(jié)果(雖然,毫無(wú)疑問(wèn),會(huì)比較慢)。

數(shù)學(xué)協(xié)處理器有八個(gè)浮點(diǎn)數(shù)寄存器。每個(gè)寄存器儲(chǔ)存著80位的數(shù)據(jù)。在這些寄存器中,浮點(diǎn)數(shù)總是儲(chǔ)存成80位的擴(kuò)展精度。這些寄存器稱(chēng)為ST0,ST1,ST2,...ST7。浮點(diǎn)寄存器與主CPU中的整形寄存器的使用方法是不同的。浮點(diǎn)寄存器被當(dāng)作一個(gè)堆棧來(lái)管理?;叵胍幌露褩J且粋€(gè)后進(jìn)先出(LIFO)隊(duì)列。ST0總是指向棧頂?shù)闹?。所有新的?shù)都被加入到棧頂中。已經(jīng)存在的數(shù)被壓入到堆棧中,為了為新來(lái)的數(shù)提供空間。

在數(shù)學(xué)協(xié)處理器中同樣有一個(gè)狀態(tài)寄存器。它有幾個(gè)標(biāo)志位。只有4個(gè)用來(lái)比較的標(biāo)志位將會(huì)提到:。這些位的使用將在以后討論。

指令

為了很容易地將普通的CPU指令和協(xié)處理器指令區(qū)分開(kāi)來(lái),所有的協(xié)處理器助詞符都是以F開(kāi)頭。

導(dǎo)入和儲(chǔ)存

用來(lái)將數(shù)據(jù)導(dǎo)入到協(xié)處理器寄存器棧頂?shù)闹噶钣袔讞l:

導(dǎo)入和儲(chǔ)存

將堆棧中的數(shù)據(jù)儲(chǔ)存到內(nèi)存的指令同樣也有幾條。其中有幾條指令當(dāng)它們儲(chǔ)存好一個(gè)數(shù)后,會(huì)將這個(gè)數(shù)從棧中彈出(也就是刪除)。

導(dǎo)入和儲(chǔ)存2

加法和減法

每一條加法指令都是計(jì)算ST0和另一個(gè)操作數(shù)的和。結(jié)果總是儲(chǔ)存到一個(gè)協(xié)處理器寄存器中。

加法和減法
加法和減法2

減法指令是加法指令的兩倍,因?yàn)樵跍p法中,操作數(shù)的次序是重要的。(也就是說(shuō), a+b = b+a,但是,a-b ≠ b-a)。對(duì)于每一條指令,都有一條跟它次序相反的反向指令。這些反向指令要都是以R或RP結(jié)尾。圖6.5展示了一小段代碼:對(duì)一個(gè)雙字?jǐn)?shù)組的元素求和。在第10和第13行中,你必須指定內(nèi)存操作數(shù)的大小。否則匯編器將不會(huì)知道內(nèi)存操作數(shù)是一個(gè)單精度浮點(diǎn)數(shù)(雙字)還是雙精度數(shù)(四字)。

數(shù)組求和的例子

乘法和除法

乘法指令和加法指令完全類(lèi)似。

乘法和除法

不要驚訝,除法指令和減法指令非常類(lèi)似。除以0結(jié)果將是一個(gè)無(wú)窮數(shù)。

乘法和除法2

比較

協(xié)處理器同樣能執(zhí)行浮點(diǎn)數(shù)的比較操作。FCOM家族的指令就是執(zhí)行比較操作的。

示例

這些指令會(huì)改變協(xié)處理器狀態(tài)寄存器中的比特位的值。不幸的是,CPU直接訪(fǎng)問(wèn)這些位是不可能的。條件分支指令使用FLAGS寄存器,而不是協(xié)處理器中的狀態(tài)寄存器。但是,使用幾條新的指令可以相當(dāng)容易地將狀態(tài)字的比特位傳遞到FLAGS寄存器上相同的比特位中。

示例2

圖6.6展示了一小段樣例代碼。第5行和第6行將比特位傳遞到FLAGS寄存器相同的比特位中了。傳遞了這些比特位,所以它們就類(lèi)似于兩個(gè)無(wú)符號(hào)整形的比較結(jié)果。這也是為什么第7行使用JNA指令的緣故。

比較指令的例子

Pentium處理器(和它以后的處理器(Pentium II and III))支持兩條新比較指令,用來(lái)直接改變CPU中FLAGS寄存器的值。

改變CPU中FLAGS寄存器的值

圖6.7展示了一個(gè)子程序例子:使用FCOMIP指令來(lái)找出兩個(gè)雙精度數(shù)的較大值。不要把這些指令和整形比較函數(shù)(FICOM 和FICOMP)混起來(lái)。

FCOMIP指令的例子


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)