本文接上文程序是如何在計算機上被執行的?(上篇:軟件部分),主要內容是機器語言如何在計算機硬件上運行,關於邏輯門,加法器,布爾運算,亦即,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,理解了語言的解析和執行、理解了分層和抽象,完。