從模擬電路到計算機軟體
第一次寫文章,隨意講講電子計算機的體系結構的各個抽象層次,探討了一下造出計算機的可能性,算是給我上的課程做個整理吧:)但是電子計算機已經是發展了大幾十年的體系了,不可能事無巨細地講,看官們就隨意看看
-----------------------------------
初中的時候就在想,電腦這種東西怎麼可以這麼神奇,怎麼可能能用電路堆出這麼複雜的、可交互的設備,還能幹這麼多事,上網聽歌玩遊戲,內涵開車看蘿莉,簡直無所不能。聽別人說了幾萬年,電腦無非就是101010,我的哥啊,我也知道啊,然而並沒有什麼卵用啊,還是不知道為什麼有造出電腦的可能性。
然後上了大學學習了一波,上了幾門課,發現還真有可能:)
初中的時候,以前以為電路是這樣的
上了電子電路以後發現電路也可以是這樣的
很重要的不同的不止是電路拓補複雜了,還有就是多了很多迷之器件。然後構成計算機的一個很重要的電路元件,就是晶體管(Transistor)。而晶體管是實現數字電路很重要的一類器件,初中只知道一些最基礎的模擬電路肯定是想不懂了。
晶體管(Transistor)
嚴格意義上講,晶體管泛指一切以半導體材料為基礎的單一元件,包括各種半導體材料製成的二極體、三極體、場效應管、可控硅等。就拿三極體來說事
1947年12月23日,美國新澤西州墨累山的貝爾實驗室里,3位科學家——巴丁博士、布萊頓博士和肖克萊博士在緊張而又有條不紊地做著實驗。他們在導體電路中正在進行用半導體晶體把聲音信號放大的實驗。3位科學家驚奇地發現,在他們發明的器件中通過的一部分微量電流,竟然可以控制另一部分流過的大得多的電流,因而產生了放大效應。這個器件,就是在科技史上具有劃時代意義的成果——晶體管。因它是在聖誕節前夕發明的,而且對人們未來的生活發生如此巨大的影響,所以被稱為「獻給世界的聖誕節禮物」。這3位科學家因此共同榮獲了1956年諾貝爾物理學獎。
反正三極體是可以用小電流控制大電流,類似的還有場效應管(FET,Field Effect Transistor),這個就是用小電壓控制大電流,而且功耗低,易集成。有些場效應管可以作為一個開關——這就有點關鍵了,因為開和閉就對應著0和1,讓這些101010有了比較實在的電氣化載體。
上圖,柵極G(Gate)就是小電壓,這個小電壓可以控制漏極D(Drain)→源極S(Source)的電流,半導體這麼神奇的性質,簡直黑科技啊!
邏輯門(Logic Gate)
講道理的話,把模擬電路進行一下抽象的話,我們就可以站在數字電路的角度看問題。
無論是三極體還是場效應管,都需要一個大電壓VDD來驅動。然後一般情況下,我們把 小於0.35VDD的輸出電壓叫做0,大於0.65VDD的晶體管輸出電壓叫做1,中間的礙手礙腳盡量躲開,這樣一來我們的世界裡就剩下010101要考慮了,電壓電流什麼的再見吧。這個剩下1010要考慮的就是數字電路了,電壓電流什麼的是屬於還未進行抽象的模擬電路的範疇。
所以講道理,這些能看作開關的晶體管如果做一些非常巧妙的迷之組合的話,是不是有機會實現一些邏輯功能呢?
是!(微笑臉)
可能各位學c/c艹的時候也有接觸過一些位操作,什麼bitwise and &,bitwise or |,bitwise xor ^ ,bitwise not ~,等等。偷偷跟你們說,這些神奇布爾代數操作,是可以用晶體管的迷之組合來實現的。(當然也可以不用晶體管,不展開講,略略略)
隨便看看下圖的常見邏輯門
A,B都是輸入信號,然後經過一個「邏輯門」的黑箱操作,得到相應的輸出,想要補補課的童鞋請百度布爾代數,邏輯門等關鍵詞。
然後po幾個黑箱的內部情況:
上圖是NOR---或非門
上圖是NAND---與非門
看不懂嗎?沒事,隨便看看就好,我也不明覺厲,但是聰明的讀者們,你們一定也能feel到確實有可能這麼實現邏輯門的,是吧(微笑臉)
組合邏輯(Combination Logic)
用上面實現的神奇邏輯門的組合,我們可以構成一個組合邏輯電路 。像下圖一樣,把多個門組合在一起,並不形成循環的迴路(cyclic path),就是組合邏輯電路了。
雖然可能有多個輸入,但是由於邏輯電路的特點,所以輸入是一定可以窮舉的而且確定的輸入就有確定的輸出,於是就可畫出真值表(Truth Table)。
例如上圖甲是單一個與門的真值表,把輸入的1010排列組合窮舉以後,一定能寫出對應的所有輸出。
真值表這種東西是在說,無論多複雜的組合邏輯電路,窮舉輸出硬爆就好了:)
至於邏輯式化簡、布爾代數、卡諾圖 等就不展開講了。
時序邏輯(Sequential Logic)
這個東西有區別於組合邏輯,就是邏輯門的輸出可以往回跑,形成一個迴路(cyclic path),主要實現了數據的儲存(或者說數據當前狀態的保持)。這個也是挺重要的,時序電路可以實現SR鎖存器(SR Latch),D鎖存器(D Latch),D觸發器(D Flip Flop)等用做保持電平當前狀態的時序電路,最終還能用於實現寄存器(Register)。不過這裡也是一筆帶過=。=
加法器(Adder)
這東西感覺很好很強大啊?我第一次聽的時候,有點被嚇尿了的趕腳,邏輯門能做算數運算這麼厲害?於是趕緊學習一波。
半加器(Half Adder)
前面不是說了嗎,複雜的邏輯,窮舉就好了啊。
如果我們只考慮1bit的加法,那麼我們就有2個操作數的輸入,1個結果輸出,還有一個進位的輸出,一共4根線。
看上圖的1bit加法器的黑箱表示,左邊兩根線A,B就是輸入,S是結果,C是進位
看真值表可以寫出S和C關於A,B的布爾表達式:
論1bit的加法,兩位輸入X,Y的組合只有四種情況,可以全部枚舉出來。S是當前位的運算結果,C是要滾到下一位的進位 (Carry Out)。
具體地用邏輯門實現,可以像下圖一樣
那———為什麼叫半加器呢?直接叫加法器不就好了么
全加器(Full Adder)
那講道理的話,實用的加法器不可能只能算1bit的加法吧,怎麼也搞個4bit 8bit 16bit什麼的。那就有個小問題了,從第二位開始往後要接受多一個前一位的進位(Carry In),要把當前位的兩個操作數和上一位滾下來的CarryOut——一共3個bit都綜合一下才靠譜。所以下面的組合電路可以搞一個1bit全加器(也可以用兩個半加器加其他邏輯門實現一個全加器)
然後把全加器串聯(呃或者說串接吧)在一起,就可以做一個行波進位加法器(Ripple Carry Adder),反正就是,把n個全加器插在一根竹籤上,就可以實現n bit數字的加法了。
當然這個n bit加法器是延遲比較高的,雖然是納秒級別,但是作為一個這麼簡單和重要的基礎功能,還是需要更快的優化。這就有了超前進位加法器(Carry Lookahead Adder,CLA)等,名字和技術很厲害,但其實只是優化過的延遲更低的加法器而已。
普通算術運算這裡就只說加法器了,因為減法同理,其實就是加一個負數。在2的補碼(2s complement)的二進位數字系統下(這種數字系統統一了整數的加減法,有興趣建議百度一波),正數+正數/ 正數+負數 / 負數+負數 都可以用上面的加法器實現。 這裡之所以只說加法器,是因為乘法和除法的硬體實現,還真有點厲害和玄學的,n位乘除法需要n個pass來實現,而且也要用到加法器,所以加法器很關鍵啊 >_<
所以呢,經過巧妙設計,我們還可以實現乘法器,除法器,位移器(Shifter,就是c艹里的<<和>>),比較器,甚至浮點運算的模塊.................
算術邏輯單元(Arithmetic Logic Unit,ALU)
把加減乘除,比較,位移,「旋轉」,位運算等等各種集成好的模塊再集成一個大模塊,我們就可以把它稱作算術邏輯單元ALU了。可以通過向ALU輸入一個k bit的二進位電平組合來選擇執行哪個內置好的操作/運算。
就像這樣,ALU會提供幾個口讓外部選擇ALU要執行的操作。總之,作為CPU裡面的一個核心部件,ALU是要執行計算機指令的一個非常重要的模塊。
計算機指令(Instruction)
其實到這裡已經離最底層很遠了,但是才快到了我們經常聽到的機器語言。
所謂的機器語言,外表看似是不知道在講什麼的101010,但其實是有規則可言的。一條機器指令就是一段定長的二進位數,例如32位的機器上用的指令就是32bit長度的什麼的。CPU的電路在出廠之前就寫死了,所以你能使用的就是CPU廠商提供的介面,或者說是使用規定好的指令集(Instruction Set)。簡單點理解,指令集就是給出了一系列指令的規則,哪一部分的二進位表示著執行哪一個寫死的操作,哪一部分的二進位對應著寄存器的選擇,etc....指令集可以有很多,有精簡指令集,和複雜指令集,講道理cpu生廠商都可以自己定義。下面看看MIPS的精簡指令集的部分示例(MIPS好像是個科技公司來著=。=?)
MIPS的精簡指令集里一共有31條指令,每條32bit的指令裡面,雖然可能有些部分被浪費了,但是每個部分的定義還是很清晰的,可以看下圖
MIPS指令也有幾種類型和不同的規定,具體詳細的規定其實翻翻文檔或者百度一下就有了
上面只是一個示例,用以說明計算機指令是有各種各樣規定的。實際生活中PC電腦用的Intel等高端晶元都是複雜指令集的,規定會更多更繁瑣。總之,通過進行人為地對一段二進位各部分組成及含義進行規定,一段二進位可以被看作一個操作的執行信息。
然後一段二進位程序被載入到內存以後,通過程序計數器(Program Counter)的自增和跳轉實現逐條執行二進位計算機指令。每當一個指令要被執行時,首先就會從內存里獲取指令的二進位(上面的例子的話就是把那個32bit的東西拿過來),存放在指令寄存器(IR,Instruction Register),然後被處理器控制模塊解碼,這個控制電路取到幾個塊里有用的信息,然後配合ALU,寄存器,內存等設備進行指令的執行(instruction execution)。
彙編語言(Assembly Language)
據說上世紀50年代的時候,編程這種東西是要在紙帶上打孔孔,用來表示101010,寫程序是真心的簡單粗暴得直接寫二進位的,別說演算法錯誤了,萬一手抖了下打多打少個都會gg。打好孔的紙條過機子執行。想想都覺得反人類??(黑人問號.jpg)
簡單粗暴硬爆1010的時代的基礎積累得久了,人們終於有機會開始寫點不那麼反人類的語言——彙編語言。
其實就是終於可以寫點字母數字了,雖然某些指令的助記符(Mnemonics) 還是比較反人類,但是比看得眼花的1010好多了。上面的MOV,LEA等就是指令的操作,可以翻譯成二進位機器指令的op-code操作碼的部分,其他部分也可以被翻譯成對應的二進位bit。這個把彙編翻譯和組裝彙編程序變成一系列二進位指令的東西,叫彙編器(Assembler)。因為有種直接翻譯的趕腳,所以彙編語言還是被歸為了低級語言。
高級編程語言(High-Level Programming Language)
很多理工科都要順手學的C/C++就是高級語言,其他各種Java,C#,PHP,JS,Python,Perl,Swift等各種黑科技都算是高級語言了。高級語言的存在是因為要低級語言太反人類,為了加快人類創造的腳步,就有了高級語言。高級語言的可讀性、可維護性和開發效率高的不知道到哪去了。但是其實高級語言是需要設計的,有很多複雜而又要自洽的規則,所以把高級語言翻譯成彙編語言的編譯器(Compiler)還是不容易實現的,而且就算是看著語言設計好的標準把這個語言「實現出來」就夠逆天了。
ps:第一個高級語言的編譯器應該是用彙編語言寫出來的,寫出來以後就可以幸福開心地過上美好的日子了:)
配合上具體的操作系統,程序員們開發出各種有用有趣的程序和軟體來,人們開心地用著,偶爾罵罵軟體有bug,人類幸福地生活著,程序員也在加班的道路上越走越遠 ,而我也在惦記著計算機組成課掛科的風險,微笑臉:)
-------The End------
圖侵刪,自己p比較麻煩,圖都是來自百度圖片
引用:
百度文庫-Mos管
百度百科-三極體
百度百科-彙編語言
reference有點漏,放過我吧大佬們:)
推薦閱讀: