如果你研究現代微處理器,你可能會注意到它與老式機械計算設備(如機械計算器)之間的相似之處。更具體地說,微處理器中的算術邏輯單元(ALU)與老式機械計算器有許多相似之處。ALU可以被認為是微處理器的計算器。它讀取存儲在寄存器(register)中的數字,執(zhí)行加減或移位操作,并將結果存儲回另一個寄存器。
微處理器內部的算術邏輯單元執(zhí)行算術運算。寄存器名為r1, r2和r3。
這些基本操作與計算器所執(zhí)行的操作完全相同。它有三個寄存器來保存計算過程中使用的數字:
輸入寄存器:一個5位的寄存器,你可以拉動桿來定義輸入數字。
累加寄存器:一個13位的寄存器,用于保存多次計算的結果。
計數寄存器:一個8位數的寄存器,用來記錄你做了多少加法。
奧德納計算器,發(fā)明于1873年的俄羅斯
我不會在這里詳細解釋微處理器ALU或老式機械計算器。我們將穿越更遠的時間回到算盤。這種不同形式的手動計算機器早在羅馬時代之前就存在了。
為什么要了解算盤和它的操作?因為理解算盤可以讓你看到一些更深層次的東西,將幾千年前處理數字的方法與現代微處理器的方法聯系起來?,F代微處理器是如此復雜,當你試圖理解它們時,你很容易“誤入歧途”。
算盤就像微處理器的ALU一樣。現代計算機基于二進制數系統,其中每個數字稱為位。下圖演示的算盤可以處理最多四個十進制數字。算盤上的每一列代表數字中的一個數字。
典型算盤的圖解。每一列代表十進制中的一個數字。
從右邊開始的第一列是個位,第二列是十位,第三列是百位,以此類推。這意味著,如果我想在算盤上表示數字4023,那么我就按上圖所示排列珠子。有了這種安排,加減法就很容易執(zhí)行了。如果我想加12,我只要在個位上多拉兩顆珠子,在十位上多拉一顆珠子。
加減法非常簡單,所以讓我們看看如何在算盤上做乘法。乘法運算的方式非常類似于老式機械計算器和早期微處理器的乘法運算方式,它們只有ALU,沒有專用的乘法硬件。
用算盤乘法
我們將做一個簡單的乘法:32 × 4,結果應該是128。為了執(zhí)行此操作,我們?yōu)槊恳涣兄付ㄌ囟ǖ暮x。前兩列被轉換為計數器寄存器,而第三列被定義為輸入寄存器。最后,我們讓最后兩列作為累加寄存器,它將保存最終結果。
乘法可以被認為是進行多次加法運算。在本例中,我們將對4相加32次。
乘以個位列
我們先給累加器加4次。單列中的四顆珠子向下移動。為了記錄我們已經添加了四顆珠子的數量,我們從計數器上移動一顆珠子。實際上,我們從32開始倒數到0。
我們在累加器中再加4,計數器減少到30。此時,累加器的值為8。我們還要再加30個4個。
乘以十位列
在“個位”列上移動四顆珠子30次以上會很乏味。幸運的是,我們不必這么做。相反,我們執(zhí)行一個移位操作來加快加法的速度。我們把每一顆移動的珠子算作十乘以四。這是怎么做到的?每次我們移動計數器十位上的一個珠子,我們就移動累加器十位上的四個珠子。執(zhí)行此操作一次,計數器從30減少到20,累加器增加到48(8 + 4 × 10) 。
我們再次重復相同的操作,從而將計數器從20減少到10,并向累加器添加另一個40,現在它的值為88(48 + 4 × 10)。
注意,在上圖中,我們不能再向下移動4個珠子,因為累加器的十位列中只剩下2個珠子。我們需要使用第三列,用累加器表示百位。我們用十位上的十顆珠子換百位上的一顆珠子。
此外,十位總共需要12顆珠子,我們用它來交換百位的1顆珠子和十位的2顆珠子。此時,我們已經花光了計數器上的所有珠子,可以看到最終的結果是128。
移位操作
用算盤、機械計算器或ALU都不能直接做乘法和除法。然而,我們可以輕易地用10的倍數相乘。用10、100或1000乘以一個輸入數字很容易,你所要做的就是移動1、2或3列的珠子。做2 × 4需要移動個位列中的4個珠子兩次。如果想執(zhí)行20 × 4,則將十位列中的四個珠子移動兩次。如果是200 × 4,這意味著在百位列中移動8個珠子。你所做的實際上是加法運算和移位運算的結合。
如果你看機械計算器,你將看到累加寄存器位于一個滑動條上。向左滑動一個缺口,從輸入寄存器中添加的數字將是原來的十倍。向左邊滑動兩個凹槽,輸入的數字就會變?yōu)樵瓉淼?00倍。我們也可以向右滑動,使相加的數字變小。一個有趣的效果是,滑動桿做移位,它也影響計數寄存器。假設你指定輸入寄存器為42。接下來,將桿向左滑動兩個凹槽。當你轉動手柄將輸入加到累加器中時,你將加4200。計數寄存器上會顯示100。因此,它看起來就像你擰了手柄一百次一樣。換句話說,移位允許我們大幅減少執(zhí)行加法的次數。
這些移位操作與我們在算盤上實現的沒有什么不同。關鍵的區(qū)別在于,你需要通過手動移動珠子來更新累加器和計數器。
微處理器中移位運算的使用
移位運算幫助我們加快微處理器ALU上的乘法和除法運算。因為現代的微處理器是用二進制數字系統操作的,移位操作的是2的倍數的多個輸入。因此,我們不是用10、100、1000或10000乘以輸入,而是用2、4、8、16、32等等乘以輸入。
開始編程時,這種知識實際上很有用。在20世紀90年代初,個人電腦的乘法運算非常緩慢。我們必須使用乘法來計算像素在圖形存儲器中特定x, y坐標處的位置。因為屏幕分辨率是320 × 240,你必須把y坐標乘以320,然后加上x坐標,才能得到屏幕內存中的位置。
關鍵是,我必須將任意數y乘以320無數次。這是非常慢的。解決方案是將計算改為移位和加法的組合。以下是一個簡介:
用兩個移位操作和一個加法替換乘法,這給了一個關鍵的速度提升。