【梳理】計算機組成與設計 第3章 算術 第1節 整數的四則運算(內附文檔高清截圖)

配套教材:
Computer Organization and Design: The Hardware / Software Interface (5th Edition)
這是專業必修課《計算機組成原理》的複習指引。建議將本複習指導與博客中的《簡明操作系統原理》配合複習。
在本文的最後附有複習指導的高清截圖。需要掌握的概念在文檔截圖中以藍色標識,並用可讀性更好的字體顯示 Linux 命令和代碼。代碼部分語法高亮。
計算機組成原理不是語言課,本複習指導對用到的編程語言的語法的講解也不會很細緻。如果不知道代碼中的一些關鍵字、指令或函數的具體用法,你應該自行查找相關資料。


這部分筆記做得有點趕,除法那裏沒寫好,後面我會補充內容。除法的部分可以先跳過。

第三章 算術

第一節 整數的四則運算

1、CPU核心中的算術邏輯單元(Arithmetic logic unit,ALU)用於進行算術和邏輯運算。計算機用二補數表示法表示數。無論參與加減運算的兩個數的正負性如何、是否有符號,都可以統一進行運算。兩個有符號數運算時,如結果爲負,最高位(符號位)會自動變成1。
爲了實現更快的加法,超前進位(carry lookahead)成爲了應用最廣泛的方案。其時間複雜度與操作數的二進制位數的對數成正比。
關於加法器的實現,請參考數字邏輯電路的相關資料,也可以參考我發佈的《數字設計基礎與應用》知識梳理(2.2 常用的MSI組合邏輯模塊)。

2、當負數與非負數相加時,不會溢出。理由很簡單:一個負數與一個非負數的和一定不大於這個非負數。當兩個符號相同的數相減時,不會溢出。理由相同。也可以把兩個同號的數相減看成一個非負數加一個負數,就可以套用符號相反的數相加不會溢出的理由來直接證明了。兩個同號數相加,或者用正數減負數、負數減正數,都有可能溢出。當發生溢出時,溢出部分會直接丟失。
下標是兩個有符號數相加減的可能發生溢出情況。

如果是兩個地址做運算,溢出常被忽略(注意:地址是無符號的。)MIPS中,只有在有符號數參與的運算溢出時,纔會拋出異常。不過,MIPS對立即數進行的是符號擴展,即使運算是無符號的。
C語言和Java在計算結果溢出時不產生異常,Fortran、Ada則會產生異常。

3、異常(exception)在很多計算機上是中斷的一種。關於中斷請參考複習指導《簡明操作系統原理》。
MIPS有專門的寄存器EPC(Exception program counter)來存儲導致異常的指令。發生異常後,使用專門的指令mfc0可以將EPC的值複製到一個寄存器中,方便運行在MIPS處理器上的軟件來獲得產生異常的位置。
MIPS保留了兩個寄存器k0k0、k1,它們可以被操作系統使用。類似地,MIPS中的atOS使at寄存器是留給彙編器的。保留的寄存器中的內容在上下文切換時不會被保存。OS可以使用k0和$k1來保存返回地址,以便在異常處理程序執行完畢後順利跳回產生異常的位置。

4、有的處理器處理溢出的辦法是將結果設置爲這個數據類型能夠表示的最大正數或負數。這在多媒體方面很有用,例如如果試圖將音量設置得超過最大值,就會自動糾正爲最大值。多媒體相關的指令集,如MMX,通常提供了這種處理方式。

5、最早的硬件乘法器是這樣的:

這種乘法器模擬的是筆算乘法的步驟。對兩個32-bit的無符號數進行乘法時,被乘數(multiplicand)要放在一個64-bit的寄存器裏,乘數(multiplier)則放在32-bit的寄存器裏。當乘數的最低位爲1時,將此時的被乘數加入累加結果。以後每次加法將被乘數左移一位,乘數右移一位。於是加法要進行32次。總的來說,如果每一步需要1個週期,那麼完成一次兩個32-bit的數據參與的乘法,需要大約100個週期。
很容易想到這種方法的改進策略:將被乘數的左移和乘數的右移以及累加合併到一個週期內。此外,被乘數所在的寄存器只需要32位,乘數與結果共用一個寄存器。其電路大致如下:

6、現在,幾乎所有的編譯器都會盡可能將乘法用位移代替(主要是一個因數爲2的冪次時)。因此,編程的時候無需將乘法寫成位移,編譯器會幫我們做這些優化工作。

7、對於有符號計算,一個辦法是:先把兩數的正負記錄下來,然後把有符號數轉換成無符號數並計算,再根據被乘數和乘數的正負確定符號。

8、一種改進的乘法器的實現如下圖。
它的原理仍然與第5點所說的最原始的乘法器一致,需要將32個左移位數各不相同的數加起來。於是我們用16個加法器,每個加2個數。再用8個加法器,每個加兩個。以此類推。最後一個加法器運算後的結果就是64-bit的。可見,加法器一共有5層,時間複雜度降低到了對數級別。配合保留進位(carry-save)加法器,乘法器可以更快。出於篇幅的考慮,我會單獨歸納更快的加法器和乘法器的實現,在本複習指導中就不專門給出了。

9、最初的除法器和運算過程如下。

32位除數(divisor)、餘數(remainder)都保存在64位的寄存器裏,其中除數保存在左半部分;商(quotient)的寄存器則是32位的。ALU也是64位。這個除法器模擬的是手算除法的過程,餘數的初始值是被除數(dividend),商的初值是0。
與人類不同,計算機在計算除法時並不知道除數什麼時候小於被除數,所以要將餘數先減去除數(相減的結果直接存在餘數寄存器中)。當結果爲非負時,代表除數不大於被除數,就把商先左移一位,然後把空出來的最低位寫1。如果結果爲負,那麼將減掉的除數加回去,商左移一位(新的最低位爲0)。然後把除數右移一位,繼續計算。當計算完畢後,商和餘數的寄存器中就保存了最終結果。除數爲32位,這個計算過程最多要重複33次(第一次計算時不移位,之後的移位最多共計32次)。
這個算法和硬件當然也是可以改進的。餘數減除數、商的左移和除數的右移這三個過程可以同時進行。改進的除法器中,ALU、除數和商的寄存器都是32位的,餘數寄存器依然是64位。餘數寄存器的右半部分存放的是商。

10、與乘法一樣,如需計算有符號數的除法,一個辦法是:先把兩數的正負記錄下來。當被除數和除數的符號不匹配時,把商變爲相反數。

11、我們在前面用大量的加法器來同時將乘法器中的一些過程並行化,但是這個套路不能套用在除法器上,因爲決定下一步的行爲的是本次計算中的餘數是否爲負;而乘法器中被並行的部分的中間結果是沒有任何依賴關係的。所以我們要換用別的方法。
SRT算法通過預測來加快除法的計算速率。這個算法用6個bit的餘數和4個bit的除數來嘗試猜測商的接下來幾位,並且在預測錯誤時也有相應的步驟進行糾正。
在這裏插入圖片描述在這裏插入圖片描述

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章