寫了這么久的代碼,第一次思考計算機是怎么認識自己寫的代碼并執行的
一個代碼到底是怎么執行起來的?CPU內部到底是怎么工作的?
一、什么是二進制
大家都知道計算機是二進制,即 0 和 1,但計算機中的 0 和 1 到底是什么?
就是低電平和高電平的意思,0 代表低電平,1 代表高電平。比如 0.2V 是低電平的話,那么 5V 可能就是高電平了。一般兩者都有一個閾值,當電壓大于某個閾值時,即是高電平;當電平小于某個閾值時,即是低電平。計算機中的 0 和 1 是為了理解方便,給低/高電平取的別名。
同時兩種稱呼分別代表了數字電路和模擬電路。
數字電路是電路是以“0”和“1”及相應的邏輯符號來表示的,如下圖:
數字電路
模擬電路是電路中以電壓高低和電流等參數來表示的,如下圖所示:
模擬電路
可以看做建筑施工圖和建筑實物圖的關系:數字電路主要是表現其邏輯和功能,模擬電路是搞定采用什么材料什么方式來實現數字電路想要達到的結果!
高低電平如何實現的?
二、二極管
二極管是用半導體材料(硅、硒、鍺等)制成的一種電子器件,具有單向導電性。
一個二極管的實物圖:
二極管
邏輯電路圖(即抽象的)
二極管
電流可以從正(+)極流向負(-)極,此時處于導通狀態;但反過來卻不行,此時處于截止狀態。這就是單向導電性!
由于單向導電性,二極管就像是一個開關:
當處于導通狀態時,開關閉合,兩邊電壓大小一致,如正極 (+) 電壓為 5.2V,那么負極 (-) 也為 5.2V。
當處于截止狀態時,開關斷開,兩邊電壓大小不一致,如負極(-)為 5.2V,正極 (+) 電壓為 0V。
三、邏輯運算與門電路
與門
通過二極管可以獲得“0”和“1”,利用這個特性,我們可以制作一些有趣的電路,比如【與門】
與門
通過小學 1 年級的知識,我們可以知道,此時 uA、uB 只要有一個是 0V,那 uY 就會和 0V 直接導通,導致 uY 也變成 0V。只有 uA、uB 都是 10V,uY 也才是10V。
并且可以把電路進行封裝,不關心具體的二極管、電阻這些元器件,統一用 & 符號表示,就是上圖右側的描述。
這個裝置成為【與門】,把有電壓的地方計為 1,0V 電壓的地方計為 0。至于具體幾 V 電壓,那不重要。
或門
再來分析一個或門:當輸入中至少有一個“1”時,輸出為“1”,若全為“0”,則輸出“0”。
剛剛的與門展示的是兩個輸入,現在來看看四個輸入!
或門
當 A、B、C、D 四個輸入都是輸入低電平 0 時,四個二極管都處于截止狀態,此時輸出即為低電平 0。
當其中任意一個不為低電平時,若A為高電平 1,此時第一個二極管導通,輸出即為 A 的電平,即高電平 1。
或門在數字電路中還可以表示為:
或門
其他還有【非門】和【異或門】,跟這個都差不多。都可以用二極管或者三極管做出來,實際并不是用二極管三極管做的,因為它們太費電了。實際是用場效應管(也叫MOS管)做的。
運算離不開邏輯運算,也就是門電路,常見的邏輯運算有與、或、非、異或、同或。它們的真值表與邏輯符號如下。
邏輯電路表
四、加法器
然后我們就可以用門電路來做 CPU了。當然做 CPU 還是挺難的,我們先從簡單的開始:加法器。
對于一個簡單的加法器而言有兩個輸入(A/B)和一個輸出(Sum)和一個進位(C)。
輸入 A | 輸入 B | 輸出 Sum | 進位 C |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
只看輸入 A、B 和 輸出 Sum,發現是異或門!
只看輸入 A、B 和 進位 C,發現是與門!
也就是說加法器可以由異或門和與門構成!如下圖所示:
半加器
到這里,我們已經做出了一個最簡單的 CPU,但是現在這個只能稱為“半加器”,最多只能計算 1+1,如何更進一步,比如 1+2, 2+2?
這就需要在原本的加法器增加一個進位接口,如下就是“全加器”:
全加器
兩個半加器電路可以實現一個全加器。
前一個半加器將用于將 A、B 相加以產生部分和。
后一個半加器用于將 CIN 與前一個半加器產生的和相加,以獲得最終的 S 輸出。
任何半加器邏輯產生進位,就會有一個輸出進位。因此,COUT 將是半加器進位輸出。
每次都這么畫實在太麻煩了,我們簡化一下
全加器
將兩個加法器串聯在一起,就得到一個可以進行 2 位數(例如 3 + 2)的加法器。
2bit 加法器
進行 A + B 計算,例如 3 + 2 的和,3 的二進制是 11 (A1A0),2 的二進制是 10 (B1B0),
先算 A0 + B0,輸出 C1 = 0,S0 = 1,再計算 A1 + B1 + C1,輸出 S1 = 0,C2 = 1,最終的結果由C2、S1、S0 拼成 1012 = 5。
要幾位加法就用幾個加法器串聯,如四位(15+15):
4bit 加法器
現在我們就有了一個 4 位加法器,已經達到了小學 2 年級的水平,是不是特別給力?
五、減法器
減法器其實是本質還是通過加法器實現的,比如 5 - 3,其實就是 5 + (-3)。
十進制 | 原碼 | 反碼 | 補碼 |
---|---|---|---|
5 | 0000 0101 | 0000 0101 | 0000 0101 |
-3 | 1000 0011 | 1111 1100 | 1111 1101 |
先將十進制轉為補碼,再將補碼輸入全加器,這樣就做到了減法計算。
六、乘法器
做完加法器我們再做個乘法器吧,當然乘任意10進制數是有點麻煩的,我們先做個乘2的吧。
乘2就很簡單了,對于一個2進制數數我們在后面加個 0 就算是乘 2 了,比如
5 = 101(2)
10 = 1010(2)
所以我們只要把輸入都往前移動一位,再在最低位上補個零就算是乘2了。
那乘 3 呢?簡單,先位移一次(乘 2)再加一次。乘 5 呢?先位移兩次(乘 4)再加一次。
所以一般簡單的 CPU 是沒有乘法的,而乘法則是通過位移和加算的組合來通過軟件來實現的。
現在假設我們有加法器了,也有一個位移1位的模塊了。把這兩個模塊串聯起來你就能算 (A + B ) * 2
了!激動人心,已經差不多到了小學 3 年級水平。
那我要是想算 A * 2 + B
呢?
簡單,把加法器模塊和位移模塊的接線改一下就行了,改成 A 先過位移模塊,再進加法器就可以了。
改個程序還得重新接線?
所以你以為呢?編程就是把線來回插啊。
編程
早期的計算機就是這樣編程的,幾分鐘就算完了但插線好幾天。而且插線是個細致且需要耐心的工作,所以那個時候的程序員都是清一色的漂亮女孩子,穿制服的那種。
七、選擇器
雖然和美女作伴是個快樂的事,但插線也是個累死人的工作。所以我們需要改進一下,讓 CPU 可以根據指令來相加或者乘2。
選擇器
這個就簡單了,sel 輸入 0 則輸出 i0 的數據,i0 是什么就輸出什么。同理 sel 如果輸入 1 則輸出 i1 的數據。
有這個東西我們就可以給加法器和乘2模塊(位移)設計一個激活針腳。
這個激活針腳輸入 1 則激活這個模塊,輸入 0 則不激活。這樣我們就可以控制數據是流入加法器還是位移模塊了。
八、觸發器
現在我們終于可以做 A × B + C
了,這就需要先保存 A×B 的結果,在與 C 相加,等等...保存?話說在計算機內部是用什么方式保存數據的呢?
由于保存數據的重要性,電路中使用何種方式可以保存數據。比如使某個器件一直輸出高電平,那不就是 1 了嗎?一直輸入低電平,那不就是 0 了嗎?這里再引入一個觸發器。
觸發器
這個模塊的作用是存儲 1bit 數據。比如上面這個,R 是 Reset,輸入 1 則清零。S 是 Set,輸入 1 則保存 1。RS 都輸入 0 的時候,會一直輸出剛才保存的內容。
注意到這個電路跟之前我們看到的都不一樣了,其門電路的輸出會作為自身的輸入,這種結構被稱為反饋電路。
我們用觸發器來保存計算的中間數據(也可以是中間狀態或者別的什么),1bit 肯定是不夠的,不過我們可以并聯,用 4 個或者 8 個來保存 4 位或者 8 位數據。這種我們稱之為寄存器。
九、匯編
現在我們把上述用到的元器件組合起來,共有 8 個引腳,其中 4 個數據引腳,4 個指令引腳。數據引腳是可以輸入數據,指令引腳是用來選擇執行的操作。
我們定義,當指令引腳輸入:
0001 讀取數據,將數據引腳的數據讀入寄存器;
0010 選擇加法器,將數據引腳的數據與寄存器數據相加,結果在寄存器;
0100 選擇乘法器,將寄存器的數據乘以數據引腳的數據,結果在寄存器;
1000 清空寄存器。
我們以一個計算題來舉例:3 × 5 + 6,輸入依次為:
0001 0011 # 讀取數字 3
0100 0101 # 選擇乘法器,乘以 5
0010 0110 # 選擇加法器,加 6
不錯,現在我們計算出 3 × 5 + 6,可以去小學 3 年級踢館了,呃,不過是不是有點麻煩,這還是我們只定義了 4 種指令,要是成千上萬種這誰頂得住?
我們不妨對指令稍微包裝一下,規定:
0001 用 MOV 表示
0010 用 SHL 表示
0100 用 ADD 表示
并且假設現在又多了一個元件可以實現十進制到二進制的轉換,那么命令應該為:
MOV 3
SHL 5
ADD 6
稍微好受一點了,這就是我們每個人都精通的匯編語言,之前僅有 0 和 1 的語言稱為機器語言。
太棒了,靠這臺我們設計的 CPU 可以打敗所有的小學生,稱霸小學校園了。而且現在我們用的是 4 位 CPU,如果換成 8 位的 CPU 完全可以吊打初中生了!
實際上用程序控制 CPU 是個挺高級的想法,再此之前計算機的 CPU 都是單獨設計的。
1969 年一家日本公司 BUSICOM 想搞程序控制的計算器,而負責設計 CPU 的美國公司也覺得每次都重新設計 CPU 是個挺傻X的事,于是雙方一拍即合,于1970年推出一種劃時代的產品,世界上第一款微處理器4004。那家負責設計 CPU 的美國公司也一步一步成為了業界巨頭。它就是 Intel。
4004
作者:小道蕭兮
鏈接:https://www.jianshu.com/p/5985da9258c0
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。