計算機基礎第二章:算術邏輯單元(How Computes Calculate——The ALU)


算術邏輯單元(How Computes Calculate——The ALU)

一.前言

前面文章學習了邏輯門,那么一個個邏輯門是如果組合進行運算的呢?我們首先來了解計算機的運算基礎單元——ALU,ALU就是一個個邏輯門組成的運算單元。
下圖為第一個在單個芯片內的完整ALU,他是1970年發布的,這個芯片可以說是當時科技領域驚人的壯舉,但是通過這一章的學習,我們來簡做一個簡單ALU電路,功能和因特爾74181一樣。

二.“算術邏輯單元”(ALU)

如果想讓兩個數字完成相加運算,我們就要用“算術邏輯單元”(ALU)來處理,ALU就是計算機負責計算的組件,基本其他的組件也會用到它。
ALU有1個“算術單元”和一個“邏輯單元”組成

1.“算術單元”實現一個行波進位加法器

下面就通過一個例子來實現:ALU實現兩個數字相加。
我們可以用一個個晶體管去拼,把這個電路做出來,但很快就會復雜的難以理解,所以我們為了便於理解,用更高層的抽象,之前學到的邏輯門來做,我們會用到AND,OR,NOT和XOR邏輯門

1.“半加器”

我們用二進制計算時會有四種情況(要理解下面的知識,你必須要先搞懂二進制)

1.0+0=0
2.1+0=1
3.0+1=1
4.1+1=10

我們會發現前三種情況輸出和我們前面講到的異或門XOR完全一致

至於1+1=10這種情況,我們也可以用小學數學學加法的一種思想:滿十近一,只不過在二進制里,最大的個位數是1,所以要滿二近一,所以1+1=10。

我們看異或門XOR只對了一部分,就是讓1+1=0,但是沒有記錄近一位1,我們可以改進一下電路,加入一個AND門
如圖:

我們可以用XOR門的輸出記錄當前位的運算值,用AND門口輸出記錄近位值,我們放大上面這張圖,這個電路有個專門的名字——“半加器”
如圖所示:

理解上面這兩個這個“半加器”的輸入輸出后,為了便於理解,我們把這個半加器抽象為一個整體組件,如圖:

2.“全加器”

但是半加器其實只能處理“個位數”的運算,比如“111+111=1110”這個算式,如果我們只用滿二加一的思想,會出現近一位后還要運算一加一,則會出現1+1+1的運算,這種運算情況我們需要在當前位寫1,近位也要寫1,很明顯“半加器”已經無法滿足這個運算,所以我們需要對半加器進行升級,升級后的組件叫“全加器”,如圖為全加器算術表格:

我們可以用兩個半加器加上一個OR門封裝一個全加器組件,OR門的作用就是檢查近位,如圖:

全加器有三個輸入,一個近位值,一個總和值。
了解完全加器和半加器之后,我們來用它們制做一個更加復雜的8位加法器,半加器可以完美的處理二進制的“個位運算”,所以可以將半加器作為8位加法器的個位運算組件,也就是8位數的第一位和第二位值的運算,然后將個位運算結果輸入到下一個全加器,然后與8位數的第三位進行運算,運算的輸出結果再輸入到下一個全加器……以此類推到第8位的全加器
如圖是一個完整的8位加法器組件連接:

我們觀察最下面那個全加器的輸出carry,如果第九位任然有近位,代表輸入兩個數字的和太大了,超過了8位加法器的運算范圍,我們稱之的“溢出”(overflow)

小時候玩吃豆子游戲就是一個8位溢出的最好例子,當我們通關第255關后,繼續下一關游戲就會出現亂碼,因為8位的最大值是十進制的255,因此256關會造成溢出bug,這個bug也成為了厲害吃豆人的代表

若果要避免溢出,我們可以加更多的全加器,以便於操作16位或者32位數字,讓溢出更難發生,但代價是更多的邏輯門,另一個缺點是,每次近位都要一點時間,當然時間也不久,因為電子自動速度很快,但是對於如今的量級是每秒幾十億次運算,每一點時間都不容小覷的,所以現代計算機用的加法電路和我們上面說的有點不同,叫“超前近位加法器”,它更快,但做的事情也是一樣的——二進制的相加
ALU的算術單元,還可以做如下數學運算,就像前面的加法器一樣,這些操作也是由一些邏輯門構成的,我們只要簡單了解就好了。

有趣的是,你可能會注意到上面的數學運算沒有乘法和除法,那是因為簡單的ALU沒有專門的電路來處理乘除,而是把乘法多次加法來實現,你可能覺得這不是一種很好的設計,但是對於很多簡單的處理器已經足夠用了,同樣也可以節約制作的成本,比如我們生活中用到的電視遙控器,微波爐,恆溫器等等。

當然對於運算要求很高的設備如手機和電腦,它們的處理器,是有專門的乘除算術單元的。

你可能猜到了,乘法電路比加法復雜,不過也沒有什么魔法,只是很多的邏輯門罷了,有興趣的可以自行資料了解,這里就不做深入了。

2.“邏輯單元”

我們接下來講ALU的另一半:“邏輯單元”
邏輯單元用來執行邏輯操作,比如之前討論過的AND,OR,NOT操作都可以說是邏輯單元,它也能做簡單的數值測試,比如邏輯單元可以檢測一個數字是不是負數。
下面我們先來看一個“檢查ALU輸出是否為0”的電路,下面電路只有所有輸入為0時才會輸出1,這個電路我們后面文章會用到。

我們分析完上面電路后繼續回到我們文章最開始提到的因“特爾74181”,“特爾74181”用了大概七十多個邏輯門,也不能進行乘除運算,而且只支持處理4位輸出,比我們剛剛做的8位輸出的ALU還低( ´͈ ᗨ `͈ ),不過我們做的沒有人家完整,但是我們已經了解了完整的概念,如圖為“特爾74181”的邏輯門:

看這個4位的邏輯門就已經很復雜了,不用擔心,我們不必要去想這些復雜的電路,我們把這個邏輯門也抽象位為一個整體組件
如圖所示:

我們的8位ALU有兩個輸入(圖上邊兩個),我們命名為輸入A和B,都是8位(bits),我們還需要告訴ALU執行什么操作,所以我們加入一個組件來專門記錄我們的操作代碼(圖左邊),我們用4位記錄操作代碼,我們這里用“1000”代表加法命令代碼,“1100”代表減法命令代碼,操作代碼會告訴ALU執行什么操作,我們還需要一個8位的輸出(圖下邊),最后ALU還需要輸出一堆標志(flag)(圖右邊三個標志,分別是輸出是否溢出標志,輸出是否為0標志,輸出是否為負數標志),當然還可以有其他標志,我們目前只涉及這三個。
例如我們的ZERO標志判斷輸出是否為0,可以用來判斷兩個輸入值是否相等,ZERO標志里面的邏輯就用到了我們前面提到的電路,如圖所示:

三.總結

我們現在知道了,計算機的最基礎原件是如何進行運算的,后面兩章,我們在學習完內存和寄存器之后,會用ALU做一個CPU,來整體了解計算機的運行過程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM