CPU是怎麼認識代碼的?

邢小燕


提前備註:回答比較硬核,我會盡量軟化,但想了解知識還是需要耐心。CPU內傳輸的信號有兩種:高電壓和低電壓,分別代表數字信號“1”和“0”,因此CPU唯一能理解(問題中的“認識”)的語言就是由“1”和“0”寫成的機器語言。

由於程序(代碼)存儲在電腦硬盤中時,也是“1”和“0”的形式,是否就意味著,只要程序存到硬盤中,CPU就能認識呢?

答案是CPU仍然看不懂這些程序,因為以“1”和“0”形式存儲的程序和以“1”和“0”寫成的語言完全是兩回事,兩者的區別類似於漢語書和英語書都用紙和油墨印製,但依然是兩種不同的語言,不會英語的依然看不懂英語書。

要讓CPU能看懂代碼,要做相當多的工作。

現在的程序都是由C++和Java等高級語言寫成,這些語言是為方便人類編程發明的,不是為方便電腦執行而設計。

說到這裡,需要進一步說說機器語言和高級語言的差別。機器語言的最大特點是面向計算機硬件編程,簡單說就是程序員需要通曉計算機硬件知識,寫的程序要真實表示數據是如何被計算機操縱的。對程序員來說這就比較頭大,畢竟上得了“廳堂”下得了“廚房”只有少數大神能做到,加上機器語言純用“0”和“1”序列組成,既對視力是一種摧殘,也是對編程趣味的扼殺。

於是,有一幫人開始琢磨了:能不能將計算機硬件從編程中分離出來,讓硬件知識小白也能編程?

最先開竅的是藍色巨人IBM,它在其System/360計算機中引入了ISA(Instruction Set Architecture)概念,將編程所需要了解的硬件信息從硬件中抽象出來,這樣編程人員就可以面向ISA編程。由於ISA是用來描述編程時用到的抽象機器(不是具體的電腦CPU),包括了一套指令集和一些寄存器,因此,程序員只要知道ISA,不需要了解具體的硬件知識(每一兩年硬件都會換新),就可以編寫程序,在ISA相同的電腦上運行。

這樣一來,程序員不必瞭解過於專業的計算機硬件知識,不需要下得了廳堂,可以專心在“廚房”烹調程序大餐。

由此也可以看出,程序員很多都是不瞭解計算機硬件的,所以妹子們不要指望自己的程序員男朋友給你DIY電腦,或者電腦壞了,他能給你省下一筆修理費。他說不會修,那就是真的不會修。

極客漫畫《編程語言之戰》。


自從不用懂硬件也能編程的高級語言出現後,人類開始了編程上的放飛自我,經過數十年發展,高級編程語言已超過2500種。

但矛盾出現了,CPU能理解的機器語言還是那個機器語言,幾十年來沒有變化,怎麼辦?

其實,早在高級語言出現之前的彙編語言時代,聰明的計算機研發人員就開發出了專門的程序,用來將彙編語言和高級語言翻譯成機器語言,其過程相當於將英語名著翻譯成漢語著作。這種翻譯程序相當於人類中的翻譯家。

編譯器有兩種方法用於翻譯:編譯和解釋,相應的名稱是編譯器和解釋器。

兩者的區別是,編譯是在執行前把整個源程序(高級語言程序)翻譯成目標程序(機器語言程序),而解釋是一次只翻譯和執行源程序中的一行。

打個形象的比方,解釋器相當於發佈會的實時翻譯,演講的嘉賓說一句,實時翻譯馬上翻譯一句。編譯器則相當於著作翻譯家,整本翻譯完成後,再讓出版社印刷上市。

將高級語言翻譯成機器語言的過程。個人手繪比較粗糙,大家湊合看。


重點來了,從以上的內容可以看出,由於CPU不能直接理解用高級語言寫成的代碼,必須由翻譯程序翻譯成機器語言,因此翻譯程序可以極大地影響甚至決定處理器性能的發揮。如果沒有一個好的翻譯程序,那麼CPU的性能再強大,也好比茶壺裝的餃子,倒不出來。

正因為如此,谷歌在安卓4.4之後,拋棄了Dalvik虛擬機,改為ART,實際是將翻譯程序從解釋器切換到編譯器,發揮了芯片的性能,提高了程序運行效率。

現在,手機大廠包括華為、OPPO和vivo都開始重視編譯器開發,說到底就是為了發揮芯片性能,讓它不再成為倒不出餃子的茶壺。

最後總結一下,用翻譯程序把程序員編寫的程序翻譯成二進制代碼的機器語言後,CPU就能認識了,而且翻譯程序的優劣可以影響乃至決定CPU性能發揮。


魔鐵的世界


你看看海上船隻之間通過打燈光溝通是怎樣的,CPU執行代碼也是那個原理。

關鍵是約定一套信號協議。CPU只按傳入的二進制代碼執行指令,商家約定好了一套指令體系,不管什麼編程語言都通過某種方式把代碼編譯為CPU能懂的二進制指令指揮CPU工作。協議跟人與人的交流一樣,是有規矩的。舉個例子,發出一串指令,如果是以1開頭,則表示做什麼,比如做加法,那麼後面接著會發過來兩個數,CPU做加法後把結果存入特定的寄存器,程序會有後續指令去這個寄存器提取結果,放入指定的內存中,CPU按照這樣的約定解析傳入的一連串二進制數據,並一一執行。CPU能直接做什麼,根據這套指令體系來,不能直接做的,程序員負責編寫完整解決方案讓CPU能做出來,這就叫編程,整個指令序列叫程序。

CPU不認識你什麼語言代碼,那是給人閱讀的,不是給計算機閱讀的,計算機只懂編譯過的二進制指令,還必須是按照商家設計好的指令體系編制的指令序列才行。沒有什麼編程語言是高大上的,它好不好用,在於編譯器或解釋器把這些人類代碼翻譯為機器碼有多高明,守恆律在這方面仍然起作用,你寫的高級語言代碼越少,翻譯給機器執行的指令實際上越多。C入門最基礎的hello world程序,不要以為寫的很短就很得意,這程序編譯後的二進制機器碼有5K,printf()函數的源代碼有多長,可以自己去看看,但實際上你輸出一個字符串用不著完整的printf()功能,這函數其實一個低效的解釋型程序。


TonyDeng


高級語言通過編輯器轉為彙編代碼,程序運行時由另一段程序(操作系統)加載到內存中, 內存與cpu通過地址線、控制線、數據線與內存連接。cpu通過叫做IP寄存器(寄存器有很多種,可以把寄存器看做一個速度很快的內存)的硬件讀取到下一條指令在內存中的地址然後把這個地址信號通過控制線發送給內存控制器,內存控制器取出相應地址的數據,通過數據線發送給cpu,這就取到了一條機器指令。 cpu將這個機器指令分成兩段: 一段是操作數 ,一段是操作碼,cpu通過操作數操作碼來控制寄存器訪問內存、訪問寄存器、啟動cpu內置的計算相關的電路(ALU)最後更新ip寄存器的內容, 再通過ip寄存器發出的信號找到下一條指令並且執行, 週而復始直到程序遇到特殊的指令來結束這個程序。


A騎著白馬的悟空


準確的說,CPU不是認識代碼,而是記住代碼,數據總線送過來一個指令,是什麼如何執行,已經固化在CPU裡了,如何執行和固化?是通過複雜的組合,以門,非門,與非門這三種複雜的組合,實現了複雜的邏輯關係。


分享到:


相關文章: