計算機的本質
2 人贊了文章
目錄
- 1、編碼與電路——信號的轉換
- 2、繼電器——信號的傳遞
- 3、門電路——信號的關聯
- 4、加法器的設計——信號可以表示計算
- 5、觸發器——信號的保存
- 6、存儲器組織——信號可以表示地址
- 7、自動操作——信號可以表示代碼
- 8、操作系統——已有知識的一種應用而已
這是我一直以來就有的疑問,我很想知道計算機最最基本的工作原理。也找了好多的書籍,但這些只是從各個層次來告訴你計算機是由哪些部件構成,分別起了什麼作用,但仍然解決不了最最基本的疑惑,你甚至不知道這疑惑究竟是什麼。直到最近看了《編碼·隱匿在計算機軟硬體背後的語言》這本大師之作,終於對這個疑問有了較為清晰的認識。這本書好在它沒有試圖去解釋計算機各個組成部分,而是從兩個試圖用手電筒交流的孩子這樣一個需求出發,按照人最合理的慾望和思考過程,非常自然地搭建了一台最基本的計算機。甚至作者如果不說這就是計算機,也不說逐步構建的東西就叫cpu、內存,你會頗為驚訝地發現原來這就是在說計算機呀。
這本書雖然不是專業書籍,但對你第一次構建起對計算機整體的深刻理解卻是至關重要的,作者生動的講述使這本書的代入感極強,會讓你忍不住一口氣讀完,你將會認識到從幾塊電池、幾根電線,到最終構建成一台完整的計算機,其過程是如此的自然。我今天的目的就是把部永不褪色的計算機科學經典著作寫成一篇博客分享給大家,我的標題並不是書的目錄,圖片也是自己重新畫的,內容也並非書中的原文,而是按照我自己的理解,按照博文的篇幅重新構思的結果。哈哈有點難度,我們開始吧。
1、編碼與電路——信號的轉換
你今年10歲,你最好的朋友住在街對過,你們的窗子彼此相對。每當夜幕降臨,你都要隔著窗子和好友「對話」,且不能讓你的父母發現。而你們各自只有一把手電筒,這時你們會怎麼交流呢?我想一開始你們一定會覺得用手電筒交流是不可能的,但你們會想出第一個辦法,就是用手電筒比划出你們要說的每一個字。恭喜你,你已經開始探索如何用手電筒去「編碼」你們要說的話了,但顯然你們沒有抓住編碼的本質。
為什麼我們要管貓叫貓,管狗叫狗,管我看到你時心跳加速這種感覺叫喜歡呢?這是因為它便於我們說和寫,我們正是用語言來為世界的種種事物進行了編碼,而這種編碼正是選擇了對於嘴和手都最為方便的策略。但當我們去使用手電筒時,我們所選擇的編碼策略並沒有考慮它的方便性。認識到了編碼的本質,我們便會認識到,用手電筒比劃文字的方式交流是多麼愚蠢了。
那怎麼編碼才對手電筒是方便呢?我們知道,如果編碼後的所有操作都可以只用手電筒的亮滅來表示,無論對於使用者還是觀察者,都是最為清晰明了的。這種策略的編碼可以有很多種,其中一種我們所熟知的便是莫爾斯電碼。不難理解,將手電筒亮1秒對應摩爾斯電碼的「點」,亮3秒對應莫爾斯電碼的「劃」,我們便可以很輕鬆地用手電筒進行「交流」了。
不知道你有沒有發現,剛剛的這種嘗試,已經將語言轉換成為了手電筒的閃爍,而作為觀察者又可以很輕鬆地將這種閃爍轉換成為語言。因為光在兩棟樓之間可以瞬間且悄無聲息地傳遞,解決了夜間傳遞信息的難題,所以這種轉換是有意義的。我們完成了編碼與手電筒的轉換,也就能很自然地聯想到,編碼與電路也存在著類似的轉換,而且你會發現這種轉換具有更深遠的意義,電信號的傳遞具有更加靈活的優勢。試想一下如果你的朋友不是住在街對過,而是住在隔壁呢?你們可以用兩塊電池,幾根導線,兩個電燈泡來進行這種交流。如圖(只畫了一方)
燈泡就相當於之前的手電筒,只不過用手去撥動手電筒開關這個過程,轉化為了電路的開關。再次恭喜你,你已經知道了形成一台計算機最基本的兩個方面,編碼和電路。並且,你知道了他們之間的轉換,即語言信號與電信號的轉換。PS:書中還用了大量篇幅去講述為什麼燈泡會亮,從原子核的構造講起。這部分我就假裝你是知道的,如果你繞不過去這個坎,這部分可以當做專門的課題去研究下初高中物理知識。
2、繼電器——信號的傳遞
我們已經完成了偉大的第一步,即信號的轉換。但有一點小遺憾,通過對開關的打開和閉合的控制,直接反映在了燈泡的亮和滅,整個信號過程就此終結。儘管它已經能夠滿足我們「對話」這樣一個簡單的需求,但我們的目標顯然不止如此,如何讓信號得以延續呢?試想一個最簡單的場景,仍然以上面為例,假如你的朋友不是住在你的隔壁,而是在距離你一站地的另一個小區呢,也即是說當導線不能將電信號傳遞那麼長的距離時我們該怎麼辦呢?很顯然,我們想到的解決方案是,讓電信號先傳遞一段小距離,在傳遞一段小距離,最後傳遞到遠處的燈泡。再次明確一下,我們的新目標就是,讓電信號傳遞。
試想一下,我們已經做到的是,將電信號從開關處傳遞到了燈泡處,但這顯然不是我們想表達的「傳遞」。我們如何讓燈泡亮和滅這個信號,變成下一個開關的打開和關閉呢?如果完成了這一步轉換,我們只需構建n多個上面的結構,就能將信號傳遞下去了。如果你還對當初的物理知識有印象的話,你一定不會對下面的圖感到陌生。
沒錯,它叫通電螺線管,當通電時帶有磁性,可以將那個帶磁性的鐵棒棒吸下來,於是他做到了關閉第二個開關這樣一件偉大的事,我們的確通過這樣一個裝置完成了信號的傳遞。而剛剛發明的這套裝置叫做繼電器,它原本的作用是將之前已經微弱的電信號放大,作為一個中轉站,使電信號傳遞更遠的距離。但顯然它還有更為深遠的意義,就是完成了信號的傳遞。
至此,你已經掌握了信號的轉換與傳遞。雖然你可能不太相信,僅憑藉這兩種設計,你已經可以做出一台計算機了。可是事實就是如此,之後的所有設計,都是基於這兩個最最基本源。只要到目前為止你可以接受並且理解,那之後的所有令人嘆為觀止的精巧設計,也都不在話下。如果你正在從事用Java等高級語言編寫代碼,你可能覺得自己只是在應用前人的理論去創造,但其實你錯了。從這一步開始之後,我們都是在這兩個理論基礎之上搞應用的俗人罷了。
3、門電路——信號的關聯
上一部分我們做到了信號的傳遞,但這種傳遞就像是傳話一樣,你說一我也說一,你說二我就說二,是一種完全照搬式的轉換,很無腦。我們是否可以讓這種信號的傳遞稍稍帶一點「智慧呢」?回答這個問題前,我們先來看兩張你更加熟悉的圖。
沒錯,就是串聯和並聯!這兩張圖與之前最大的區別在於,多了一個開關。第一張圖告訴我們,當兩個開關同時閉合時,燈泡才會亮;而第二張圖則是當兩個開關有一個閉合時,燈泡就會亮。這便讓兩個信號之間有了某種邏輯的關係。如果你足夠敏感的話,你會發現意義不僅僅如此,通過對編碼的認識,我們知道此處開關的打開與閉合可以代表更加豐富的含義。
試想一下,如果你去寵物店買一隻貓,貓有黑白兩種顏色,公母兩種性別,你的要求是買一隻黑色的公貓,你便可以用第一張圖的電路來幫你判斷是否符合要求。我們讓第一個開關的開代表白貓,關代表黑貓,第二個開關的開代表母貓,關代表公貓。這樣每當把一隻貓拿來時,我們將開關分別置於相應的狀態,只要燈泡亮則代表符合你的要求。有沒有感覺,信號已經不再是孤立的,而是有了一點點「智慧」,它可以幫你解決選貓的問題,自然也能解決邏輯複雜的難題。那麼如果你用第二張圖做同樣的判斷,那麼你的要求一定是想選一隻黑貓或者公貓。
這兩張圖仍然用了low逼的電燈泡,而上一部分我們知道,用繼電器將電燈泡替換,我們就可以將這種邏輯信息傳遞下去,也就打破了單一電路無法描述的複雜邏輯。一旦信號可以傳遞,再配以其他各種各樣的邏輯電路的設計(這是電氣工程師乾的事),理論上我們能滿足任何複雜的邏輯要求。既然電燈泡可以用繼電器替換,那麼開關也可以理解為上一個電路通過繼電器傳過來的電信號,此時,我們將一切都歸為一種信號,而不用依賴燈泡或是開關這種具體的實物了。同時,開關所代表的的貓的顏色和公母,也可以抽象成開表示數字0,關閉表示數字1。因此,我們把這兩種電路抽象成兩種門電路,分別是與門和或門。我們必須理解下面的圖其實和上面是一樣的,如果不去做這樣的抽象,一台計算機的電路圖將會是天書。
不錯,A和B分別代表上圖的兩個開關,也可以說是輸入信號,而F則代表燈泡,更準確說是輸出信號。你必須開始習慣這種抽象。而門電路不只有這兩種,其內部結構也不都是如此簡單,你可以自行百度將常用的門電路示意圖找到並將其記住,之後的部分我將直接畫出所需要的門電路而不做這樣詳細的解釋。如果你心裡過不去這道坎,你可以親自嘗試去實現各種門電路的電路圖,這將是有意義的。但從此處往後,你必須不再糾結門電路裡面具體是怎麼實現的,而應該開始花心思去想利用這些門電路的組合與設計。因為抽象的目的就是為了封裝實現細節以便開展更深入的研究,甚至這兩個門電路內部不一定非要是用開關和電線實現的,有可能是真空管、晶體管,也有可能根本不是用電實現的,這便是抽象的魅力,好在我們已經掌握其中一種最笨的實現方式了。還是那句話,你必須開始習慣這種抽象。
4、加法器的設計——信號可以表示計算
剛剛我們所設計的門電路,已經使得信息似乎具有了某種「智慧」,但這還遠遠不夠,其實我們更需要一個能幫我們進行數學計算的電路設計。一旦打通了這一關,可以說你已經了解了計算機的全部,因為計算機所做的一切,就只有計算,更絕對一點說,計算的一切,也就只有加法。在這裡我做一個大膽的假設,正在閱讀這篇文章的你已經知道了二進位的含義。那你是否能夠用剛剛的知識,給自己做一個8位二進位數的加法計算器呢?它大概應該是這個樣子。
其實這不是一個新知識,我相信給你足夠的時間你一定會設計出來,你不妨在此暫停一段時間拿出一張紙試試。我們先從最簡單的一位數相加開始,如何設計出一個一位數相加的計算器呢?我們首先應該整理出這樣一張清晰的表,即 0+0=00;0+1=01;1+0=01;1+1=10,這裡我們直接將進位也考慮進來。
加數A加數B加和輸出進位輸出0000011010101101
不論你用什麼方法,這張表的對應關係總能轉換成某種門電路。如果你剛剛熟記了各種門電路的效果,不難發現它們的對應關係非常簡單粗暴。和就是異或門,進位就是與門。畫出來就是下面這個樣子,由於我們只考慮了向後進位,而沒有考慮前一個數的進位,因此我們稱這種裝置為半加器。
如果將前一個進位考慮進來,只需再多一個半加器就可以了,至於為什麼進位輸出的加和沒有用半加器而是用了一個或門,請暫停一分鐘思考一下。這回我們已經建立好了一個完美的一位計算器,我們便可以自豪地稱之為全加器。
一位計算器做出來之後,8位計算器就只需將全加器逐個拼起來即可,並且再次抽象整體,我們稱之為8位加法器。
OK,大功告成。我不知道你此時的感受如何,不知不覺我們連續進行了3次抽象(即把之前的器件封裝起來),有沒有深刻體會到之前所說的你必須開始習慣這種抽象。每當一個複雜的構造被裝進一個黑盒子里時,你便再也不要考慮裡面的構造了,只要你做到了這一點,這三步的抽象便會是so easy。有了加法計算器,減法也就不是問題了,在本博客中將略去這部分內容,如果有興趣,可以去了解一下計算機是如何用補碼錶示減法的,之後你會發現,減法就是加法。
5、觸發器——信號的保存
到目前為止,我敢說如果你第一次了解這些,你會感覺有些許的興奮,但我更敢說,這些東西依舊沒能解決你對於計算機最好奇最困惑的部分,因為我讀到這裡也是這種感受。沒關係,從這部分開始才是我認為最為精彩的部分,回過頭再看之前的知識簡直就是鋪墊。讓我們先從兩個能毀你三觀的一個設計開始吧。
左圖:當閉合開關A時,整個電路聯通,開關B將會被吸下來,整個電路斷開,電磁鐵失去磁性,開關B又會彈上去,此時電路又聯通,開關B又被吸下來。就這樣,開關B不斷地快速地在開和閉之間循環進行,而我們始終沒有去干預這個電路,因此該電路有了自反饋的特性。由於開關B的來回震蕩,我們將這種電路稱為振蕩器,振蕩器又通常被稱為時鐘。
右圖:這個需要稍稍繞個彎。
一開始輸入A和B均為0,此時燈泡不亮,或者說輸出為0
現在讓輸入A變為1,燈泡亮。但當A再次變為0時,燈泡仍然是亮的。也就是說輸入A除了一開始對燈泡有影響外,之後再怎麼變都是對燈泡毫無影響的。 保持A輸入為0,我們再來看B,當B的輸入為1時,燈泡滅。此時B無論是1還是0,燈泡永遠處於滅的狀態,跟A的情況剛好相反。 我們注意到,該電路好像記住了之前的信號,如果燈泡亮,則說明上一個變為1的信號一定是輸入A。我們將這種電路稱為觸發器。天吶,我們已經可以讓機器有了記憶,相信通過之前的引導,你已經知道這意義非凡。因為一旦實現了記住1位,那就意味著我們可以讓機器記住一切。但這個電路還需要小小地改善一下。我們是否能讓輸入僅僅為一位,再增加一個保持位。當保持位為1時,輸入便會記錄在輸出上,當保持位為0時,無論輸入怎麼改變,輸出仍然是上一次記住的狀態。很簡單,其實我們要做的就是將右圖中的輸入A和B之前加入一個裝置,當輸入為1時,令輸入A為1,B為0;當輸入為0時,輸入A為0,B為1。因此,我們有了如下天才般的設計。
時鐘使得我們可以控制該存儲裝置是否存儲來自輸入的信號。8個這樣的裝置組合起來,我們就創造了可以存儲8位的存儲器,我們稱之為8位鎖存器。
通過振蕩器,觸發器,以及之前提到的加法器的組合,可以做出很多有意義的部件,由於篇幅限制不做展開,但要簡單列一下我們可以完成的工作。
- 計數器:通過振蕩器和多個觸發器相連,可以做出計數器,使得信號從0000 0000 一直增加到1111 1111。
- 自動加法器:通過加法器和鎖存器的連接,可以做出能夠進行多次連續相加並保存結果的機器。
6、存儲器組織——信號可以表示地址
上面我們實現的8位鎖存器有一點缺陷,那就是它只能8位一起存入,並且是一一對應的。我們可不可以實現這樣一種裝置,使得我可以隨意選取一位輸入信號,並且讓他在指定的輸出位輸出呢?為了達成這個目標,我們首先要回答根據什麼選取。我們可以分別給8個輸入位一個編號,這裡我們就可以形象地稱之為地址。顯然,我們可以用3位的信號來表示8個不同的地址,因此我們所要實現的裝置應該是長這個樣子。
為了連貫性,將具體實現和最終的簡圖畫在了一起。我在這裡只畫了上面部分的具體實現,下面的沒有畫出,讀者可以自行思考。其實到這裡你應該明白,你不必去知道每一個實現細節,當你知道只要給你一定的時間也一定能自己畫出時,便可以省下這部分精力,適當的放棄也是抽象思維的一個表現。
我們管上面的部分叫3-8解碼器,下面的部分叫8-1選擇器,整個的部分我們可以驕傲地成為存儲器(RAM的既視感)。這套裝置實現了將一個1位的信號存儲8個位置上指定的一個位置中,並且通過輸出可以觀測到。不難發現,我們已經實現了1位信號的存和取,那麼事實上,我們已經可以存取一切了。事實上,本書講解了多位存取的裝置RAM的具體實現,僅僅是多個上述的裝置拼起來,將一位的輸入變成多位,並且有多個多位的輸入,這真的可以稱之為內存了。
7、自動操作——信號可以表示代碼
現在我們來回顧一下,我們依次實現了以下「技術」
信號的轉換(編碼)——信號的傳遞(繼電器)——信號的關聯(門電路)——信號的計算(加法器設計)——信號的保存(觸發器)——信號的地址(存儲器組織)
似乎一台計算機就快要浮出水面了,但不知道你有沒有發現一個缺陷。回想之前的加法器、鎖存器以及改造後的存儲器,始終是我們人為去控制後(例如打開開關)機器才能運轉起來,我們希望存儲時必須調整時鐘信號為1才表示可以存儲,是否可以讓一切過程自動進行呢?答案是肯定的。要做到這一點,我們需要做兩件事。
- 將手動輸入的時鐘信號等改為上一層信號的傳遞
- 需要有一個自動變化的計數器
如果將某一串信號和時鐘信號連起來,使得時鐘信號一碰到它就變成了1,存儲器開始起作用,那麼我們可以把這種信號形象地理解為代碼,當它用二進位表示時,就是機器碼。那剛剛這段代碼的含義就是,將數字存儲到存儲器中。當然我們之前所用到的信號,現在可以把它稱作數據。我們將代碼和數據這兩種形式的信號,依次存入存儲器中,利用一個用振蕩器實現的計數器依次將存儲器中的信息,按照地址順序讀出,便可以自動進行操作了。我們要做的只是:
- 設計各種機器碼和其對應的電路使其完成:載入、存儲、相加、停止、地址跳轉等基本操作
- 利用這些機器碼順序地編寫並存入內存,等待依次被讀出,我們稱之為程序
計算機就是這樣,沒啥的。本書第17章自動操作可以說是經典中的經典,篇幅限制不好表現,但都是對已有知識的排列組合了,但你會發現腦洞大開,也會有了計算機的藍圖。雖然略過,但還是要放一張書中的原圖裝個逼。
8、操作系統——已有知識的一種應用而已
好了,到這裡我就可以停止了,再往後的所謂操作系統、彙編語言、高級語言,甚至什麼大數據、人工智慧這些,統統是上述內容的擴展,其本質永遠無法逃脫那單調而神器的0和1。
PS:最後再次感謝這本大神之作《編碼 隱匿在計算機軟硬體背後的語言》,也希望大家喜歡我這篇吐血博文。如果我這篇文章寫的不夠味,最起碼能激起你閱讀這本書的興趣,我的目的也就達到了。總會有很多人告訴你大數據很火,人工智慧很火,你用該學學Java,應該去搞一搞python。但少有人會告訴你,你應該先學習最最基礎的計算機原理,雖然這在短時間內不能使你得到明顯的收益,但它會讓你在技術的道路上走得更遠。
推薦閱讀:
TAG:計算機專業 |