鏈接:https://www.zhihu.com/question/31752629/answer/53834585
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
目錄:
1. 二進制理論
2.數字電路的實現
3.CPU 對硬件的控制
4.最終章(解答樓主問題)
補充:
5.邏輯門的物理實現:MOSFET
6. 軟件控制硬件實例:SD CARD(待續)
7. I2C協議詳解(待續)
8. FPGA 與 ASIC(待續)
=========================================================
作為啃了幾年書本,燒過幾塊電池的工程狗,那我就來科普一下吧。
不算大神,唯手熟爾。
我們不妨從最底層開始往上走。
1. 二進制理論
眾所周知,電腦,手機以及其他大量的電子設備,都是基於復雜的數字電路進行工作的。而數字電路則通過循環往復地完成一系列的指令,來輸出我們想要的結果。
那究竟里面的工作原理是什么樣子的呢?
首先,我們需要一套數字理論。
上帝說,我們需要一個理論。於是萊布尼茨誕生了。
萊布尼茨提出了二進制,這成為了現代計算機理論的基礎。至於是老子啟發了他,還是他自己坐而悟道想出了二進制,其實已經不重要了。有了二進制,一切變得簡單起來:
我們可以只用1 和0 來代表所有數字,進行和十進制一樣的代數運算。雖然對於人腦來說,二進制非常不雅觀, 比如:
10001010101010101010 * 0101001101010 = 0101101001000001010011100110100。
但它對於計算機來說, 則最簡潔,最直觀,最高效。
1.1 二進制運算
每一位都只可能是1或者0,運算符號也就是加減乘除。雖然長,位數多,但速度極快!因為,但就每一位來說,運算之后,只會有幾種情況:
1 + 1 -> 0, 進一位(, 這個)
1 + 0 -> 1.
0 + 1 -> 1.
0 + 0 -> 0.
所以說,《三體》中,劉慈欣講到人肉計算機一說。單個運算單元只需要記住特定指令相對應的操作即可,甚至連加減乘除都不需要會。 但這個在現實里面並不可能完成。假設這個運算恆紀元的程序有10000條指令(但顯然這個條件都不成立,因為這個程序必然很復雜,涉及復雜的浮點運算和邏輯算法,甚至還有平方開放積分微分,10000條機器代碼都不夠塞牙縫的), 每條指令需要100個邏輯單元,每個單元的運算時間1秒鍾,那么整個程序就需要1000000s (11天13小時46分鍾)。。。所以可能程序還沒算完,亂紀元又來了,所有人來不及脫水都死了。這還不算發盒飯,上廁所時間。
1.2 二進制邏輯
而且,電腦可以理解是非對錯了。計算機以1表示“對”,“是”,“正確”。以0表示“錯”,‘否’,‘錯誤’。然后又引進了“或”,‘與’,‘否定’,等邏輯語句。
我們用 || 表示“或”,表示兩者有一個成立即成立(我是學工科的(1) || 我是學計算機的(0) = 我沒有女朋友(1))。
0 || 0 = 0
0 || 1 = 1
1 || 0 = 1
1 || 1 = 1
我們用&& 表示“與”,表示兩者都成立方可成立。(我是學工科的(1)&& 我是男的(1) = 我沒有女朋友(1))。
0 && 0 = 0
0 && 1 = 0
1 && 0 = 0
1 && 1 = 1
2. 數字電路的實現
2.1. 邏輯門
我們有了數字理論,那怎么才能做出邏輯電路呢?怎么才能用來運算呢?我們引入這些理想的邏輯門,靠他們來作運算。

這個就是與門,除非兩個輸入都是1,則輸出1, 否則輸出0.

這個就是或門,除非兩個輸入都是0,則輸出0,否則輸出1.

這個就是非門,它會對輸入取反(1變0,0變1 )

現在,僅用一個理想原件,就可以做一次邏輯運算了!
那如何做代數運算?比如加法?

當兩個輸入都是0, 高位輸出0, 低位也是0 =》 0
當兩個輸入都是1, 高位輸出1, 低位也是0 =》 2
當輸入一個0一個1,高位輸出0, 低位也是1 =》 1
所以,大家也看到了,這個邏輯電路其實並不明白加法,它只是照部就搬的給我們了碰巧正確的結果——這就是我們常說的‘中文房間’的思想實驗。
我們有了2以內的加法,那么4以內也好解決了,8,16。。。以此類推,我們只要把數字電路互相疊加,就能得到很多功能,比如說加減乘除,求余等等數學運算,相應地,邏輯電路也會越來越復雜:

我們現在有了CPU,他可以完成簡單的運算,但是這還不夠。
我們要編程。
2.2. 編程
程序本身就是指令的集合。
所謂的編程就是將程序員所要實現的效果,用系統支持的指令寫下來。就好比給你一本唐詩三百首,讓你用里面的詩句組合(雜燴)成你想要表達的意思。
當我們安裝一個程序的時候,它本身實在硬盤里面的。 只有當我們啟動它的時候,系統才會到硬盤里,找到該程序,然后將其讀取到內存中。
將設我們還在使用一個幾十年前的電腦,這個電腦每次操作只操作的數字只有八個0或者1,也就是我們常說的8位系統。這些指令被存放到內存里面之后,CPU又會把它當下要執行的那一句放到寄存器里面,然后執行這條指令。一條接一條,循環往復。
假設我們有一個8位指令。CPU得到它之后,就會分析,這一個指令里面,哪一段是操作符,哪一段是數字。比如:0101 00 11,它會讀前四位,發現是加法(我瞎編的),然后讀5-6位發現是0,7-8位是3,所以輸出3。
CPU得到3之后,會把它放到寄存器里面,然后進行后續操作。
當然看似簡單,8位操作里面的數字電路也會是無比復雜了(這還只是幾十年前的科技,如今intel 64位處理器的復雜程度可見一斑)。
至此,我們已經可以編程了。我們的程序會是這樣子。
00101010
10101010
01001101
01010010
計算機誕生之初,程序的確是這樣的。但假如讓如今的程序員來干這種事情,肯定又得哭爹喊娘一頓了(誤)。所以,后來,出現了匯編語言。比如:
MOV R1, #0x1
MOV R2, #0x1
ADD R1, R2, R1
這是ARM的匯編指令,讀出來如下
在寄存器R1里面裝1,
在寄存器R2里面裝1,
計算R1 + R2 並將值放到R1里面。
這就是一個簡單的加法程序了。
但是呢,這種程序寫起來還是很不舒服,效率極低。
於是高級語言語言。
int a1 = 1;
int a2 = 2;
a1 = a1 + a2;
這是c語言里面的一個簡單加法。這個程序被我寫完之后,會被編譯出來——也就是有一個c的編譯器,將這個程序轉換成01010101 這樣的指令(往土了說,就是個翻譯機,把人類語言翻譯成1&0)。當我們運行這個程序的時候,電腦會把這些東西放到內存里面,然后逐行的讀取,然后一行行的運算。
好了,我們可以回歸問題了。
3. CPU 對硬件的控制
3.1. 對CPU的誤解
在我學習這些東西之前,我對CPU有一種誤解。我以為在電腦里面,只有CPU是活的。換句話說,整個電腦里面,事無巨細,都是CPU一手操辦的,就像一個勤奮的全棧工程師一樣。
其實,CPU更像是個產品經理。
舉個例子,我們的電腦里面有藍牙。藍牙里面其實也有一個CPU,更確切的說,是個MCU(Micro Control Unit),它負責將無線藍牙信號解碼成數字信號等一系列的操作,而CPU得工作只是協調MCU做相應的工作而已。
給個場景:你打開了聽歌軟件,輸出設備是藍牙耳機。
軟件:哥,給我個耳機唄。
CPU:大妹子,耳機沒插,倒是有個藍牙耳機。
軟件:那哥,你告訴藍牙,俺要在他那里唱歌唄。
CPU:歐了。
CPU轉向藍牙。
CPU:嘿,那個傻大個,說你呢,瞅啥,俺大妹子要你給她干個活。
藍牙:哥,你等會兒。
藍牙:scanning devices.....
藍牙:searching for possible peripherals providing required service.....
藍牙:device BLEX00010EFD010 discovered.....
CPU: 啥玩樣兒啊,讓你干點事兒,咋這么墨跡呢?
藍牙:哥,這事兒費神,您和大妹子多擔待啊。
藍牙:bonding with BLEX00010EFD010.
藍牙:bonding succeeded.
藍牙:Bluetooth Service Linkage Established.
藍牙:哥,成了,叫大妹子開始吧。
CPU:真墨跡。
CPU轉向音樂軟件。
CPU:大妹子,開始吧。
軟件:哥,叫他唱“我是女生,可愛的女生”。
CPU:轉向藍牙。
CPU:傻大個,唱,“我是女生,可愛的女生”。
藍牙:check linkage lost?
藍牙:linkage quality good.
藍牙:signal to noise ratio: -20dB.
藍牙:transmission rate:1 Mb/s.
藍牙:我是女生,可愛的女生。。。。。
所以,在這個實例里面,CPU只是充當了協調&領導的角色。所以一個程序得以實現,其實仰仗於CPU能順暢,有效的發布指令,和得到結果。
而這些信息的通道就叫 BUS,或者叫總線。
3.2. 總線(BUS)
就像上網用網線一樣,電腦內部的通信也依賴於總線。這些總線傳輸數據,指令,地址等一系列的信息,是電腦完成各項計算和操作人物的物理基礎。在計算機內部,每一個硬件設備都以特定的方式與CPU想連。哪怕是外接設備,也可以通過USB,SD卡槽得以連接。
但單單有物理基礎還是不夠的,就像你只有電話線,只有網線,只有天線。
你還需要一些通訊協議。
4.3 通訊協議
誰都有嘴,但並不是誰和誰都可以用嘴高效正確地傳遞信息。(我就發現,一和女孩子講話,我就懵逼。) 而一門共同的語言就像是一個協議,確保雙方所言所聞都能被正確的處理。總線也一樣,也需要有一套既定的協議,得以讓信息能在CPU和MCU之間正常往來。比較常用的協議有SPI, I2C, UART, 等等。這些協議規定了,什么指令表明什么含義,什么時候可以發信息,有幾條數據線,電壓多少,頻率多少,等等。事無巨細,一律都有非常嚴謹統一的規定。
為了不讓看官厭煩,我也不會跟老學究老教授一樣說一堆,如果后面有空間,我可以舉幾個例子,這邊我暫且按下不表。
4. 最終章:總結暨對這個問題的直接回復
當程序員在電腦的終端寫下一行命令,比如說"turn off the bulb"(我們假設有個程序員在CPU上接出一根電線到一個小燈泡上面) 。從打下到執行有如下步驟。
我們的這句話會被編譯成若干個指令,就像(瞎編):
0101 0000(翻譯:CPU把0寫到內存里特定的位置),
00010101(翻譯:通過總線,用I2C,叫一下小燈泡的MCU),
然后小燈泡被叫了一下之后,自己到約定的這個內存為止去讀數字,發現是0,所以輸出0,這個0 就是個低電壓,可以理解成0V,然后0V和5V與邏輯之后,就是0V,所以小燈泡就關了。
當然,我上面也純屬扯淡,這個指令不可能用短短幾行代碼來完成。使用I2C協議本身可能就需要超過一百條代碼:通過吧某些地方的電壓拉低,某些地方的電壓拉高,來完成通信,有點類似黑幫片里面交易雙方互相閃車燈。
今天先寫這些,后面有時間會再補充一些內容。
看官們鼓勵一下把。
-------補充-------
5. 邏輯門的物理實現:MOSFET
有了理論上的邏輯門,現在需要做的,就是着手設計切實可用的邏輯元件。從最開始的陰極管到現在的晶體管(Transistors),在過去的大半個世紀,這些邏輯元件的實現經歷了數次更新迭代。無論在速度,穩定性上,都出現了質的飛躍。
今天,我們就來講一下MOSFET(metal–oxide–semiconductor field-effect transistor,金屬氧化物場效應晶體管),它是現如今電子行業用的最多的邏輯元件,比如說我們常聽到CMOS技術等等,就是基於MOSFET。
但是,在開始之前,我們必須先涉獵枯燥的,玄幻的,又非常重要的半導體理論。
5.1. 硅
一切都要從硅開始說起。
硅,其實並不稀奇。
地球上最多的元素:氧硅鋁鐵。這個我們都會背。
如果說沒有貝爾實驗室和那一群伯樂(我忘記那些科學家的名字了),可能硅還是會很平凡的,作為砂石,存在這個星球上。
硅,基於我非常有限的高中化學知識:四價,共價鍵,非常穩定,不易得電子,不易失電子。
除了穩定,看似沒什么鳥用。但是,當少量的+3/+5價單質(如:Ga/As)被混入硅之后,我們就真的化腐朽為神奇了。
比如說,假如我們把0.1 Mol的As混入了1 Mol的Si之后,因為As為+5價,所以相比於Si,那個多出來的電子非常活躍,容易脫離原子核。這就導致一塊不帶電的混合物里面,有大量的(這里,大量只是相對於一塊Si單質)帶正電的原子核(+5As丟了一個電子)和同等量的游離電子(e)。我們稱這塊混合半導體為n-type(negative)。
到這里其實非常好理解。easy peasy。
同理,我們可以想象把0.1 Mol的Ga混入另外一個1 Mol的Si里面。這時候,那些牛逼的理論物理學家在這時候引入了穴的概念(Holes)。因為Ga特別容易得電子,導致有些Si的電子會被Ga偷取,留下了一些穴,而這些穴,就像+1的電子,也會不停的運動。我們稱這個半導體為p-type(positive)。
然后,當我們把一個p-type 和一塊n-type放在一起的時候,神奇到讓人無法相信的事情發生了。
(我覺得我可能都講不清楚~~~~~~~)
5.2. PN Junction(PN 結)
我們可以自己做一下思想實驗,接觸面兩邊鄰域的電子和穴會互相中和,導致這一塊區域(depletion region)的電子和穴非常稀少,而那些固定的原子核(包括帶+1的As和帶-1的Ga)並不會變化。他們會造成一個穩定的電場,阻止了其他地方的電子和穴涌入。於是一個動態穩定(dynamic equilibrium)形成了,如圖。

當我們施加一個正向電壓的時候,depletion region會因為電壓的緣故變薄,大量的電子和穴得以穿過,造成很強的電流。而當我們施加一個反向電壓的時候,depletion region會變厚,電流無法通過。
wah lah ~
5.3. 場效應晶體管
有了這個理論,后面要做的就不難了。(Bazinga!寫到這里我已經徹底懵了,我是照着參考書寫的。)
一個MOSFET就長這樣。


當我們不給Gate這個電壓的時候,我們得到了兩個典型的PN Junction(Drain & Subtract, Subtract & Source),電流是無法流過的。
當我們給Gate施加一個正電壓的時候,Gate的上層帶正電,下層則帶了負電。但因為Gate是個不導電的金屬氧化物,所以它的下部會形成一個n type 通道(induced electron inversion layer)--電子可以直接從Source流到Drain。於是,我們得到了一個電流通路。
這就是我們的邏輯開關了。
最后,我們需要了解,MOSFET可以分為兩種,一種叫P-MOS, 一種叫N-MOS。我們上面的圖例其實是NMOS因為整個的載體為電子。很顯然,PMOS的載體就是穴,它的source和drain都是P-type。
在現實的使用中,兩者的區別就是:
High Gate Voltage Low Gate Voltage
PMOS 斷路 通路
NMOS 通路 斷路

5.4. CMOS (Complementary MOSFET BALABALA)邏輯電路
單個的MOSFET似乎並沒有神力,但當若干個mosfet組合到一起,我們就可以很輕松的得到各種我們想要的邏輯門。

這個圖例看起來很復雜,但其實是個紙老虎。首先,我們給Vdd通5V電源。
假設兩個輸入都是1, 即5V。對照5.3.的最后的表格
Q1: 通
Q2: 通
Q3: 斷
Q4: 斷 (Q1 和Q2 通導致Q5和Q6的Gate連到了5V,也即高電壓上)
Q5: 通
Q6: 斷
所以,輸出連接到了Vdd,也即5V,也即1.
同理,其他易證。
7. I2C協議詳解
8. FPGA 與 ASIC