程式是如何在計算機上被執行的?(下篇:cpu工作原理)
本文接上文程式是如何在計算機上被執行的?(上篇:軟體部分),主要內容是機器語言如何在計算機硬體上執行,關於邏輯閘,加法器,布林運算,亦即,cpu的工作原理。
1、邏輯閘
以下圖片是《三體》中的一個情節:
這段故事提到一千萬個這樣的門部件,就是搭建計算機的基礎元件,邏輯閘。
那什麼是與、或、非呢?
相信聰明的你高中物理有學過電路,想象三種場景:
1、非門開關控制燈泡,1是開啟,0是關閉
2、與門
串連電路,只要關一個開關,燈泡就不亮,只有兩個開關都開啟燈泡才亮,即必須都是1才亮。
3、或門
並聯電路,只要有一個開關是開的,燈泡就亮。
道生一,一生二,二生三,三生萬物,就像人體蛋白質由二十種氨基酸通過不同組合而成,使用這三種基本邏輯閘,就可以實現所有邏輯運算,進而構造出一整套的計算
一切運算的基礎——加法
現在能生成萬物的基礎元素與或非門出現了,接下來我們著手設計CPU最重要的能力:計算,以加法為例。由於CPU只認識0和1,也就是二進位制,那麼二進位制的加法有哪些組合呢:
-
0+0,結果為0,進位為0
-
0+1,結果為1,進位為0
-
1+0,結果為1,進位為0
-
1+1,結果為0,進位為1,二進位制嘛!
注意進位一列,只有當兩路輸入的值都是1時,進位才是1,看一下你設計的三種組合電路,這就是與門啊,有沒有!
但,只有計算能力是不夠的,電路需要能記得住資訊。
神奇的記憶能力
到目前為止,你設計的組合電路比如加法器天生是沒有辦法儲存資訊的,它們只是簡單的根據輸入得出輸出,但輸入輸出總的有個地方能夠儲存起來,這就是需要電路能儲存資訊。
電路怎麼能儲存資訊呢?一位英國物理學家,設計了這樣一個簡單但極其神奇的電路:
這是兩個NAND門的組合,不要緊張,NAND也是有你設計的與或非門組合而成的,所謂NAND門就是與非門,先與然後取非,比如給定輸入1和0,那麼與運算後為0,非運算後為1,這就是與非門,這些不重要。
比較獨特的是該電路的組合方式,一個NAND門的輸出是兩一個NAND門的輸入,該電路的組合方式會自帶一種很有趣的特性,只要給S和R段輸入1,那麼這個電路只會有兩種狀態:
要麼a端為1,此時B=0、A=1、b=0;
要麼a端為0,此時B=1、A=0、b=1;
不會再有其他可能了,我們把a端的值作為電路的輸出。
此後,你把S端置為0的話(R保持為1),那麼電路的輸出也就是a端永遠為1,這時就可以說我們把1存到電路中了;而如果你把R段置為0的話(S保持為1),那麼此時電路的輸出也就是a端永遠為0,此時我們可以說把0存到電路中了。
就問你神奇不神奇,電路竟然具備儲存資訊的能力了。現在為儲存資訊你需要同時設定S端和R端,但你的輸入是有一個(儲存一個bit位嘛),為此你對電路進行了簡單的改造:
這樣,當D為0時,整個電路儲存的就是0,否則就是1。
同理,我們可以通過任意加法器進行組合拼接實現較長的二進位制計算。實際上,數學家已經證明,加法是實現所有數學運算的基礎。有了加法器,原則上就可以通過他們搭建任何其他計算,像乘法、除法、平方、開方、三角函式等。而偉大的電腦科學家圖靈在一百年前就已經指明,這些簡單運算足以支撐任何資訊處理的過程。
暫存器與記憶體的誕生
現在你的電路能儲存一個位元位了,想儲存多個位元位還不簡單,複製貼上就可以了:
我們管這個組合電路就叫暫存器,你沒有看錯,我們常說的暫存器就是這個東西,類似於平常運算過程用到的可擦寫草稿紙。
上圖左側是十六進位制操作碼,右邊是將資料從一個暫存器複製到另一個暫存器的操作。
你不滿足,還要繼續搭建更加複雜的電路以儲存更多資訊,同時提供定址功能,就這樣記憶體也誕生了。
暫存器及記憶體都離不開上一節那個簡單電路,只要通電,這個電路中就儲存資訊,但是斷電後很顯然儲存的資訊就丟掉了,現在你應該明白為什麼記憶體在斷電後就不能儲存資料了吧。
以上就是cpu計算的原理了,如前所述,真正的計算機在執行的時候,是通過逐條讀取存放在記憶體中的相應指令,然後進行計算和操作實現的。被機器所識別並執行的機器指令或操作指令,會被編碼成方便人類理解的築基形式,就是組合語言。
再接上一篇文章程式是如何在計算機上被執行的?(上篇:軟體部分),從後往前讀,就是整個程式在計算機上執行的流程了。
總結:
回顧一下,程式語言是經過如下流程在計算機上執行的:
程式語言---語法分析、詞法分析---轉換成組合語言---機器指令---cpu執行---邏輯閘---與或非
這樣看,所有語言,不管是js,python,go還是其他的,最終都會被解析成組合語言在cpu上執行。那麼,所有語言,都是等價的,所有語言都可以通過編譯器實現從一種語言到另一種語言到轉換。
當計算機執行程式時,我們會發現每一層表現形式不一樣,但本質都是計算,而且每一層都是建立在下一層基礎上的抽象。雖然分了很多層,所有層都是等價的,層和層之間有明確邊界,越到下層牽涉到的基礎單元越多,越到上層越簡潔。
抽象對我們在電腦科學中做的每件事都很有幫助。抽象使得編寫一個大型程式成為可能,將其劃分為小而且容易理解的部分,用C這樣的高階語言編寫這樣的程式不用考慮彙編,用匯編寫程式碼不用考慮邏輯閘,用邏輯閘來構建處理器不用太多考慮電晶體,抽象是如此重要。
不管是計算機網路分層原理,計算機系統,應用…都有抽象,都是為了讓使用者更易用更好用,至此,理解了cpu,理解了語言的解析和執行、理解了分層和抽象,完。