组建一台计算机3_硬件3 多位运算器
前言:
放假有一周的時間,到家也有四五天的時間了,這幾天把《code》好好的看了一遍。盡管之前也有草草翻過,但是把時候我就曾告訴自己,無論如何都是要把書中的這些東西都實現(xiàn)一遍的。于是說干就干,這幾天基本上就在搞這些東西了。這些學(xué)習(xí)成果要感謝余富帥給我傳的軟件以及一些推薦。
=========================================================================
轉(zhuǎn)載請遵循GNU開源宣言。Copyleft ! <2013>, <http://www.cnblogs.com/sciencefans?from buaa 華羅庚班>
閱讀此文,你需要擁有以下基礎(chǔ):
1.小學(xué)代數(shù)相關(guān)知識;2.初中電路;3.高中門電路相關(guān)知識;4.本系列之前兩節(jié)的內(nèi)容;5.二進(jìn)制和十進(jìn)制的轉(zhuǎn)換(這一點不會也沒有關(guān)系)。
之前已經(jīng)做好了一個對位加法器,對于減法和負(fù)數(shù)的運算支持的不是很好。所以現(xiàn)在應(yīng)該研究一下負(fù)數(shù)和減法運算應(yīng)該如何實現(xiàn)。
在解決這個問題之前,會遇到另一個問題:我們?nèi)粘I钪?#xff0c;想表達(dá)一個負(fù)數(shù)是很自然的事情:-2,-33.2,-10等等。但是在計算機里可不是這么容易。首先他沒有‘-’這個符號,它所能接受,處理以及存儲的東西只有兩個——0和1.我們在大學(xué)生計算機基礎(chǔ)課上學(xué)過:在機器中的數(shù)字用補碼的形式存儲。但是當(dāng)時沒有人深究它的原因也沒有人思考前輩們是如何想到用補碼來存儲一個數(shù)字的。非常巧,這個問題在研究減法運算的時候解決了。
如果想表示一個負(fù)數(shù),那么應(yīng)該用某一個位來表示正負(fù)。既然我們通常愛把正負(fù)號放在數(shù)字的最左端,那么何不把一個對位(這里以8位舉例)的最左端的那個位的0,1狀態(tài)定位正,負(fù)的表達(dá)呢?但這意味著能表示的數(shù)的絕對值范圍縮減了一半,但是為了能達(dá)到負(fù)數(shù)的表示,這樣做是值得的——大不了把機器字長再擴大一倍。
如果現(xiàn)在想計算253-176是多少,也就是在計算1111 1101 – 1011 0000.
不難發(fā)現(xiàn)253 – 176 = 253 + ((255 - 176)+ 1) – 256。
先不用想為什么要這樣變換,馬上就會明白。
化成二進(jìn)制之后就變成:1111 1101 +? ((1111 1111 – 1011 0000) + 0000 0001) – 1 0000 0000
首先計算括號里的。非常明顯,1111 1111 – 1011 0000這一步是在對1011 0000取反。那么我們用一個取反器就可以實現(xiàn)(8位取反器也就是8個(甚至可以壓縮至一個)非門的并聯(lián))。最后一個減法是9位運算,只需要使之前運算的第九個進(jìn)位溢出拋棄即可(當(dāng)然也可以存下來)。而其他的又是我們在之前非常熟悉的純加法運算了。
這樣一來,很容易回答之前的問題——為什么要這樣變換?——就是為了能夠把減法湊成取補和溢出拋棄這兩種門電路運算,這樣就能讓電路能實現(xiàn)減法運算了。
回頭再想一想大一上學(xué)期剛剛學(xué)習(xí)過的補碼:正數(shù)不變,負(fù)數(shù)絕對值取反后加1,不正是兩個括號里的運算嗎?
然后,負(fù)數(shù)運算器便可以順利成章的畫出來:
首先,我們要制作一個取反器:
?
最上方的輸入是決定是否取反,如左圖,讓取反位為1的時候,對數(shù)據(jù)取反,左邊的數(shù)據(jù)輸入為0101 0101,輸出為1010 1010.當(dāng)取反位為0,則不取反,左右相同。本電路僅僅使用了‘抑或’門,它的電路圖在之前的加法器中已經(jīng)做過介紹。
緊接著,我們要把之前做好的8位加法器和這個取反器相連:
這里需要說明的是,兩個元件的電路圖都可以在這一篇和上一篇文章中得到。紅色框所圈的輸入位代表應(yīng)該運行加法還是減法,當(dāng)運行加法,位值為0,當(dāng)是減法,位值為1.很顯然,當(dāng)是減法的時候,輸入1,取反器對藍(lán)框輸入的數(shù)字進(jìn)行取反,8位加法器對粉色框的被減數(shù)和藍(lán)色框的減數(shù)的逆進(jìn)行相加,得出的值就是相減的結(jié)果。當(dāng)是加法,紅色框位值為0,則取反器不取反,加法器將兩數(shù)相加。
但是一定會有人有這樣的問題:取反后的加一哪去了?我保證仔細(xì)讀下去5分鐘內(nèi)你就會明白——這是這個設(shè)計的最精妙之處。
這里還有兩處非常精妙的地方:黑框和8位加法器上方的輸入。這里給出解釋:
1.上下溢出問題:我們應(yīng)該都思考過這2個問題——如果兩個加數(shù)相加和超過了8為存儲的范圍該怎么辦?兩數(shù)相減如果減出負(fù)數(shù)怎么辦?這兩個問題分別成為上溢和下溢。為了解決這個問題,可以設(shè)計出黑框里的輸出位——第9輸出位,當(dāng)是減法并且下溢的時候,它會輸出1,這一點不難分析得知。當(dāng)是加法并且發(fā)生上溢,他也會輸出1.這樣一來,完美的解決了這個問題。
2.進(jìn)位問題:還記得之前我們?nèi)绾沃谱?位加法器的嗎?我們把8個單位加法器相連。但是我們把最低位的那個單位加法器的進(jìn)位輸入位給接地了——也就是默認(rèn)為二進(jìn)制的‘個位’沒有接收到進(jìn)位。但是當(dāng)我們要實現(xiàn)減法的時候,就不是這么輕松了——還記得之前那個算式嗎?對減數(shù)取反后要加上一。如何實現(xiàn)呢?因為如果是減法,紅框?qū)斎?,那么何不把這個‘1’加到取反之后的那個減數(shù)上呢?bingo!就這么辦,直接把這個1當(dāng)成個位的進(jìn)位就好了~比如說23+45本來等于68,給他的個位進(jìn)上一位就是69,自然就是+1的效果啦~
好啦,所有原理都解釋清楚了,那就試一試吧!
算一算圖靈的生日吧~他是6月23日出生,那么我們分別計算6+23,6-23,23-6是多少。
首先6,23的二進(jìn)制分別是0000 0110和0001 0111.,下面三幅圖分別是上面三個運算:
??
口算一下,答案完全正確!分別是29(0001 1101),-17(m1110 1111),17(0001 0001).
需要注意的是:第二個-17正是-17的補碼——17的反碼加1.
再看看第三個結(jié)果17,對比一下-17和17的二進(jìn)制碼,再想想補碼的定義,你一定能感到非常奇妙和有趣!
最后的最后我們再來看看開始的那個問題:
253 – 176 = 253 + ((255 - 176)+ 1) – 256 = ?
用我們的運算器來做一下!
運算器給出的結(jié)果是0100 1101,也就是77的二進(jìn)制,口算一下。。恩。。。完全正確!
至此,我們已經(jīng)做出了一個比較完善的運算器。
但是人類永遠(yuǎn)不會滿足——我怎么樣才能把計算的數(shù)據(jù)和結(jié)果一直存到電腦里,這樣我就可以不擔(dān)心我能忘掉他們了。
為了解決這個問題,我們設(shè)計的電腦必須具有存儲器。它的解決方案就在:http://www.cnblogs.com/sciencefans/p/3188284.html
轉(zhuǎn)載于:https://www.cnblogs.com/sciencefans/p/3185368.html
總結(jié)
以上是生活随笔為你收集整理的组建一台计算机3_硬件3 多位运算器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 开发时遇到的各种问题1-
- 下一篇: linux下的共享库(动态库)和静态库