我和小宇早戀了,咱們家住隔壁。程序員
晚上父母會把手機沒收,但咱們還想繼續聊天,又不敢發出聲音,因而咱們想到了這個辦法...編程
咱們把全部的中文都用燈泡的亮滅組合來表示,同時約定好每隔一秒讀取一次燈泡的狀態並記錄下來,這是咱們的暗號。併發
我:亮亮滅滅亮app
喜:滅亮亮滅滅ide
歡:亮滅亮滅亮編碼
你:亮亮亮滅滅spa
這樣,咱們雖然沒有了手機,依然能夠日以繼日地聊天,雖然效率很低,但依然很快樂。設計
我和小宇就這樣在不經意間,將語言轉換成爲了燈泡的亮滅組合,這個過程叫作編碼。blog
我和小宇就這樣一直祕密保持着通話,直到上了大學,父母再也管不了咱們用手機了。內存
但這麼多年的小燈泡通話,使咱們總以爲事情沒那麼簡單,因而咱們開始了一些新的探索。
咱們增長了一個開關。此時當兩個開關同時閉合時,燈泡纔會亮。
這樣兩個開關與燈泡之間,再也不是以前簡單的對應關係了,而是有了邏輯。
開關的斷開與閉合分別對應着電路的斷開與連通。而小燈泡的不亮與亮,也分別對應着電路的斷開與連通。那這二者就能夠統一,再也不依賴於具體的實物表現了。
還有,開關的連通與斷開,是主動的。而小燈泡的連通與斷開,是被動的,是結果。
咱們把開關這裏的連通與斷開稱爲輸入端,把燈泡的連通與斷開稱爲輸出端,而且將整個電路都封裝在一個圖形裏,能夠獲得以下抽象:
咱們決定把這種電路叫作門電路, 上面這個叫與門。
爲了從此更爲抽象的探索,咱們將電路連通表示爲數字 1,電路斷開表示爲數字 0。
咱們將這種表示方式稱爲二進制。
輸入 A |
輸入 B |
輸出 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
慢慢地,咱們發現了愈來愈多的玩法。
上面這種電路,我把他抽象成以下門電路形狀,叫作或門。
以後便一發不可收拾,我和小宇設計了愈來愈多的門電路,咱們發現,只要是咱們能想到的邏輯關係,均可以設計成對應的門電路。
十進制數能夠轉換成二進制數,而二進制數又能夠對應到門電路的輸入端與輸出端。
因而我和小宇有了一個大膽的想法,能不能設計一個計算加法的電路呢?
咱們首先從最簡單的一位二進制數相加開始:
0+0=0;0+1=1;1+0=1;1+1=10
變成一張表格以下
加數 A |
加數 B |
加和輸出 |
進位輸出 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
即咱們須要設計出一種電路,能夠達到表中的輸入與輸出效果。
通過不懈努力,終於發現這個電路能夠由異或門和與門兩個門電路組成。
這個裝置實現了二進制的一位加法,但它並不完美,由於只考慮了這兩個數的進位輸出,但沒有考慮上一位的進位,因此只能叫半加器。
若是將前一個進位考慮進來,只需再多一個半加器,而且拼接一個或門便可。
此時咱們已經創建好了一個完美的一位加法器,並自豪地稱之爲全加器。
全加器作出來以後,不管多少位的加法器就均可以作出來了,只需將全加器逐個拼起來便可。咱們嘗試作一個八位加法器。
OK,大功告成,有了加法器,理論上就能夠實現任何的數學運算了。
由於咱們知道乘法能夠轉換成加法,除法能夠轉換成減法,而減法又能夠轉換成補碼的加法。如今咱們能夠自豪地稱這個部件爲,算術邏輯單元 ALU。
我和小宇都很是高興,終於用電路的方式實現了計算功能。
但慢慢的以爲沒什麼意思了,因而咱們又突發奇想,設計了以下詭異的電路。
當閉合開關 A 時,整個電路聯通,開關 B 將會被吸下來,整個電路斷開,電磁鐵失去磁性,開關 B 又會彈上去,此時電路又聯通,開關 B 又被吸下來。
就這樣,開關 B 不斷地快速地在開和閉之間循環進行,而咱們始終沒有去幹預這個電路,所以該電路有了自反饋的特性。
因爲開關 B 的來回震盪,咱們將這種電路稱爲振盪器,因爲它能夠產生不斷變化的電信號,就像時鐘同樣不停且規律地跑着,咱們將這個裝置又稱爲時鐘。它所產生的交替的電信號稱爲時鐘信號。
雖然有了加法器,可是輸入的數字從哪裏來?能不能先保存在某個地方呢?
我和小宇通過屢次實驗,發明了一個很是複雜的電路:
若是輸入端爲 1,改變"某控制端"信號(信號由 0 變化到 1 這個瞬間),則輸出端變爲 1,以後輸出端仍然保持(存儲)着剛剛的 1。
若是輸入端爲 0,改變"某控制端"信號,則輸出端變爲 0,以後輸出端仍然保持(存儲)着剛剛的 0。
若是想不明白也不要緊,只要記住這個電路的設計,實現了一位的存儲功能!咱們叫它 1 位鎖存器。
而後咱們把多個鎖存器組合起來,再加上一些 3-8 譯碼器,8-1 選擇器等電路,就能夠實現一個能保存 8 位二進制的存儲器,而且能夠隨機地讀寫它, 咱們把它叫作 RAM,簡稱爲內存。
這個組件經過再次組合,能夠造成 N × M 的 RAM 陣列。好比咱們能夠表示一個 1024 * 8 的 RAM 陣列。
這表示存儲容量爲 1024 個單位,每一個單位佔 8 位。
爲了更方便地表示,咱們規定 1024 = 1K,8 位 = 1 字節(8 bit = 1 byte),那麼咱們就能夠說,這個 RAM 的存儲容量爲 1K 個單位,每一個單位佔 1B。或者說,地址空間爲 1K,存儲容量是 1KB。
此時這個 RAM 模塊已經近乎完美了,咱們甚至能夠單獨對其進行使用,將數據存入某個地址,將某個地址中的數據讀出。
怎麼方便人操做呢?只須要將地址輸入、數據輸入、寫操做端分別接入一個控制面板,由開關來控制這些信號的輸入是 1 仍是 0 便可,而後再將數據輸出接入一些燈泡方便觀察,這樣一個單獨的能夠手動操做的存儲裝置,就搞定啦。(下圖中有彩蛋~)
有了可讀寫的內存,咱們就能夠事先把幾個數字存儲內存中了,接下來,咱們可否讓算術邏輯單元 ALU 自動地讀取這個數字,進行加法運算呢?
咱們先引入一個新的組件,10 位計數器,這裏的 Clk 就接入咱們在第四部分講的時鐘信號,Clr 是清零端,具體效果下面動圖一目瞭然。
計數器的輸出就是 0,1,2,3,4,5,能夠看成內存中的地址。
咱們把這個計數器,以及上面講的 ALU 與 RAM 所有連在一塊兒,嘗試實現一個能夠累積求和的裝置。
咱們想計算的是 1+2+3+4+5+6+7, 這個自動化的計算器是這麼運行的
一、用控制面板在 RAM 的地址 0~6 處存上 1~7 這幾個數字的,在上一節已經實現了。
二、當計數器的值是 0 時,數據 1 被輸出到加法器進行計算,此時加法器 A=1,B=0,計算結果爲 1,但記住鎖存器存儲的是上一次的加法器輸出 0,此次的計算結果要等下一次鎖存器遇到上升沿信號。
三、當計數器的值是 1 時, 數據 2 被輸入到加法器,此時鎖存器存儲了上一次的計算結果 1,並將這個 1 輸出給小燈泡,並同時回傳到加法器的B,因此此時加法器 A=2,B=1,計算結果爲 3
四、當計數器的值是 3 時,以此類推,請看下圖
咱們將累加求和這個過程自動化了!以後若是想計算累加和,只須要用控制面板事先在內存裏存好數據就能夠了!是否是很方便?
咱們還想要更多的自動化!
如今這個裝置,只能無腦地將 RAM 中的數據從頭至尾一直累加下去,沒法選擇加哪一個不加哪一個,也沒法選擇何時中止。
好比咱們 RAM 中的數據是這樣的。
地址(16 進制) |
數據(10進制) |
0x00 |
... |
0x01 |
10 |
0x02 |
... |
0x03 |
20 |
0x04 |
30 |
0x05 |
... |
... |
... |
咱們只想讓 RAM 藍色地址處的數據進行累加,其餘地方的數據忽略,而且到 RAM 0x05 處就中止,該怎麼作呢?
咱們能夠再增長一個 RAM,這個 RAM 裏存放的數據,表示"指令"的含義!
咱們先發明三種指令。
add:把 RAM 這個位置處的值進行累加
nop:忽略此處的值(也就是什麼都不作)
halt:中止(禁止計數器的值加一)
那麼要想達到上述功能,相應的這個指令 RAM 中的數據應該是這樣的。
注意:下面指令 RAM 的地址和上面數據 RAM 的地址之間有一一對應關係!
地址 (16 進制) |
指令RAM的值
|
指令含義 |
0x00 |
nop |
什麼都不作 |
0x01 |
add |
累加 |
0x02 |
nop |
什麼都不作 |
0x03 |
add |
累加 |
0x04 |
add |
累加 |
0x05 |
halt |
中止 |
... |
... |
... |
咱們須要引入一個控制單元,放在以下位置。
遇到 nop 指令(0x00),那輸出就將鎖存器的 W 位禁止,不容許鎖存器寫操做,這樣累加結果就不會錄入。
再好比遇到輸入爲 halt 指令(0x05),就將計數器的 EN 位禁止,不容許計數器 +1,這樣就達到了中止的效果。
此時再讓時鐘信號震盪起來,就能夠達到有選擇地求和過程,而且在指定位置懸停。那如今咱們就讓時鐘信號震動起來,看看這個過程吧。(此處只留關鍵組件)
這個控制單元該怎麼實現呢?咱們知道,只要給出輸入,給出輸出,任何組件均可以造出來。本文就再也不展開了。
有了三個指令,咱們知道了經過指令這種方式,配合各類複雜的控制器,便可實現將全部操做通通自動化。
接下來咱們須要作的,就是設計控制器,以及約定好一大堆指令,使得經過這一大堆指令的排列組合,能夠實現任何自動化的計算操做。
咱們將設計好的一大堆指令
稱做指令集
咱們將指令排列組合後能夠實現的功能
稱做程序
咱們將指令的排列組合這個過程
稱做編程
咱們將排列組合這些指令的人
稱做程序員
而咱們將承載這一切的裝置,叫作什麼呢?
沒錯,這個破玩意,就是
計算機
本文靈感來自一本計算機科普神做,《編碼 | 隱匿在計算機軟硬件背後的語言》,我在此向這本書致敬。我把核心思想提取出來,寫成了低併發風格的文章,送給各位讀者。若是你對計算機對總體原理十分困惑,但願本篇文章可讓你稍稍解惑。同時但願你們找時間能夠將本書通篇閱讀,我保證你會頗有收穫的。本文和本書的核心目的是讓你理解計算機的思想,實際上如今的計算機指令與數據都是放在內存中的,文中其餘地方也都是對計算機的簡化模型,且不可出去真的和人家說計算機是個破玩意,尤爲不準說這是低併發編程的閃客告訴你的喲~