其實CPU是不認識程序員寫的代碼的,這需要編譯器當中間的翻譯官,在說方舟編譯器的時候說過這些,這里更系統(tǒng)的說一下,會涉及到的計算機課程包括《計算機組成原理》、《電子電路》、《匯編語言》、《編譯原理》、《C/C /JAVA 程序設(shè)計》等。 某種意義上來說算盤就是一種早期的計算機,算盤計算需要的是什么?數(shù)據(jù)和操作,比如“1 1”這個運算“1”就是數(shù)據(jù),“ ”就是對數(shù)據(jù)進行的操作。經(jīng)過這么多年的發(fā)展,我們的電腦可以干很多很多的事情了,但是本質(zhì)上還是在做類似“1 1”的操作。 目前所接觸到的計算機都是以馮·諾依曼體系結(jié)構(gòu)為主,結(jié)構(gòu)如下: 簡單說就是CPU從外面取數(shù)據(jù),然后在內(nèi)部通過運算器做運算,最終將計算結(jié)果輸出,控制器則是對程序規(guī)定的控制信息進行分析,控制并協(xié)調(diào)輸入,輸出操作或內(nèi)存訪問。 CPU是一顆數(shù)字電路芯片(還有模擬電路芯片),他是怎么制造出來的呢?可以參考Intel制作的從沙子到芯片的短片,如下:
CPU上面主要是晶體管電路,晶體管只有兩個狀體:高電平和低電平,在計算機中用0(false)和1(true)表示,通過0和1能表示多少東西呢?前面我們說CPU的本質(zhì)就是計算,只有兩個狀態(tài)如何計算“1 1”,“2 2”呢?有一個數(shù)學分支——布爾代數(shù)。布爾代數(shù)只有兩個數(shù)據(jù)表示:true(1)和false(0),運算符也沒有加減乘除,只有:NOT(非)、AND(與)、OR(或)(讀起來好像跟鬧太套很像)。 以AND(為例),只有兩個都為true,結(jié)果才是true,有一個為false結(jié)果就為false,這種看似神奇的邏輯本來是證明哲學的,所以。。。 在布爾代數(shù)中,只需要通過,NOT(非)、AND(與)、OR(或)來實現(xiàn)運算,其實還有個常用的XOR(異或)。運算解決了,數(shù)字怎么解決,只有0和1怎么表示那么多的數(shù)字?這個大家都能想到——二進制就行了,可是程序中不僅有數(shù)字還有字母呢,怎么搞?提前編碼,就是ascii表,實際上我們輸入一個大寫字面“A”,在里面對應(yīng)的就是二進制0100 0001(十進制65); 有了布爾代數(shù)以及ascii表,計算機就可以表示所有的數(shù)字和字母(初期不支持漢字)以及符號了,下面就可以設(shè)計門電路了,CPU就是由各種門電路組成的: 到了這里可以很容易得出一個結(jié)論,CPU用0和1就可以搞定數(shù)據(jù)和運算,CPU是搞定了,對CPU來說各種0和1的組合就是它能讀懂的“語言”,這就是我們所說的機器語言。0和1這種語言也是人來規(guī)定的,人當然也能讀懂,但是當面對非常龐大的一堆的0和1時,任誰都會崩潰,這太反人類了。 于是匯編語言誕生了,匯編語言與機器指令是一一對應(yīng)的,比如我們要計算1 1,如果直接輸入機器碼會是很長的一串0和1的組合,如果是匯編語言(8086)呢?大概就是下面的樣子: mov ax, 1 //寄存器ax送入值1, 是不是很容易看懂了?寄存器又是什么呢?是CPU內(nèi)部暫時存儲指令、地址、數(shù)據(jù)的元器件,intel的64位處理器中有16個寄存器。 又說起硬件了,我們繼續(xù)說軟件,匯編語言有很多指令和助記符幫助程序員,所以這些程序編寫起來會方便很多,那CPU是如何理解匯編器的呢?其實機器也不懂匯編語言,把匯編語言轉(zhuǎn)換成都是01的機器語言需要匯編器(Assembler),其實就是匯編語言編譯器,但是這個很底層,用二進制寫的,機器可以讀懂這個翻譯。 對程序員來說,匯編語言確實比機器碼方便了,但是依然會設(shè)計寄存器,地址等,想要做一個大型軟件還是很麻煩,這就有了C語言等,后來又有了JAVA、python等高級需要,比如要用C語言寫一個'1 1',就是下面的形式: int x; 是不是更簡單了,C語言一樣效率不高,因為想要更好的描述世界,進行大型程序開發(fā)面向過程的語言是力不從心的,于是就有了面向?qū)ο?,有了反射等機制。不管是C語言還是JAVA、python等,都是為了方便程序員更好的抽象和描述世界,描述需求。機器依然不懂,編譯器因此誕生了,編譯器就是把程序員用的各種高級語言翻譯成處理器 才懂的機器語言。 上面我一直說的CPU都是基于Intel 的8086處理器,課本上也一直是這個,現(xiàn)在應(yīng)該也還是,但是事實上現(xiàn)在已經(jīng)有很多的處理器已經(jīng)不是X86處理器了,ARM和X86的區(qū)別是什么呢?ISA(An instruction set architecture , 指令集架構(gòu))不同,我們還說上面最簡單的A B的描述,在不同的指令集上,他們的實現(xiàn)是不一樣的,也就是我們平時說的架構(gòu)不同,所以同一個程序最后編譯到不同架構(gòu)的處理器上得到的機器碼也是不同的,無法移植。 那能不能跨平臺呢?在IT界,加個中間層沒有什么不可以的,比如JAVA就是增加了一個虛擬機,JAVA的虛擬機就是JAVA跨平臺的基礎(chǔ)。 |
|