內核目錄kernel/math目錄中包含數學協處理器仿真處理代碼文件,共包含9個C語言程序,見表11-1。本章內容與具體硬件結構關系非常密切,因此需要讀者具備較深的有關Intel CPU和協處理器指令代碼結構的知識。但好在這些內容與內核實現關系不大,因此跳過本章內容并不會妨礙讀者對內核實現方法的完整理解。不過若能理解本章內容,那么對于實現系統級應用程序(例如匯編和反匯編等程序)和編制協處理器浮點處理程序將有很大幫助。
11.1 總體功能描述
在計算機上執行計算量較大的運算通常可以使用三種方法來完成。一種是直接使用CPU普通指令執行計算。由于CPU指令是一類通用指令,因此使用這些指令進行復雜和大量的運算工作需要編制復雜的計算子程序,并且一般只有通曉數學和計算機的專業人員才能編制出這些子程序。另一種方法是為CPU配置一個數學協處理器芯片。使用協處理器芯片可以極大地簡化數學處理編程難度,并且運算速度和效率也會成倍提高,但需要另外增加硬件投入。還有一種方法是在系統內核級使用仿真程序來模擬協處理器的運算功能。這種方法可能是運算速度和效率最低的一種,但與使用了協處理器一樣可以方便程序員編制計算程序,并且能夠在對程序不加任何改動的情況下把所編程序運行在具有協處理器的機器上。
在Linux 0.1x甚至Linux 0.9x內核開發初期,數學協處理器芯片80387(或其兼容芯片)價格不菲,并且一直是普通PC中的奢侈品。因此除非在科學計算量很大的場合或特別需要之處,一般PC中不會安裝80387芯片。雖然現在的Intel 處理器中都內置了數學協處理器功能部件,從而現在的操作系統中已經無須包含協處理器仿真程序代碼,但是因為80387仿真程序完全建立在模擬80387芯片處理結構和分析指令代碼結構基礎上,因此學習本章內容后讀者不僅能夠了解80387協處理器編程方法,而且對編寫匯編和反匯編處理程序也有很大幫助。
如果80386 PC中沒有包括80387數學協處理器芯片,那么當CPU執行到一條協處理器指令時就會引發“設備不存在”異常中斷7。該異常過程的處理代碼在sys_call.s第158行開始處。如果操作系統在初始化時已經設置了CPU控制寄存器CR0的EM位,那么此時就會調用math_emulate.c程序中的math_emulate()函數來用軟件“解釋”執行每一條協處理器指令。
Linux 0.12內核中的數學協處理器仿真程序math_emulate.c完全模擬了80387芯片執行協處理器指令的方式。在處理一條協處理器指令之前,該程序會首先使用數據結構等類型在內存中建立起一個“軟”80387環境,包括模仿所有80387內部棧式累加器組ST[]、控制字寄存器CWD、狀態字寄存器SWD和特征字TWD(TAG word)寄存器,然后分析引起異常的當前協處理器指令操作碼,并根據具體操作碼執行相應的數學模擬運算。因此在描述math_emulate.c程序的處理過程之前,有必要先介紹一下80387的內部結構和基本工作原理。
11.1.1 浮點數據類型
本節主要介紹協處理器使用的浮點數據類型。首先簡單回顧一下整型數的幾種表示方式,然后說明浮點數的幾種標準表示方式以及在80387中運算時使用的臨時實數表示方法。
1.整型數據類型
對于Intel 32位CPU來講,有三種基本無符號數據類型:字節(byte)、字(word)和雙字(double word),分別有8、16和32位。無符號數的表示方式很簡單,字節中的每個位都代表一個二進制數,并且根據其所處位置具有不同的權值。例如一個無符號二進制數0b10001011可表示為:
U = 0b10001011 = 1×27 + 0×26 + 0×25 + 0×24 + 1×23 + 0×22 + 1×21 + 1×20 = 139
它對應十進制數139。其中權值最小的一位(20)通常被稱為最低有效位(LSB,Least Significant Bit),而權值最大的位(27)被稱為最高有效位(MSB,Most Significant Bit)。
新聞熱點
疑難解答