cpu架構、cpu指令集、彙編語言、交叉編譯、高級語言/編譯器程序、自舉、編譯和解釋

一、cpu指令集
cpu是什麼?
cpu就是cpu芯片,也叫處理器。是機算機系統用來處理程序的硬件。被處理數據的格式必須是二進制。
cpu指令集是什麼?
cpu指令集就是cpu指令的集合cpu指令集規定了很多操作運算,cpu指令集的數量也很多,如常見的x86指令集和arm指令集,還有一些小衆的指令集如Mips指令集,龍芯就是用mips指令集的。
cpu指令是什麼?
cpu指令就是某個規定的操作運算機器碼(二進制數據)。
爲什麼cpu指令是二進制數據?
因爲cpu只能處理二進制數據,那麼做爲cpu指令,肯定是要輸入到cpu中,然後由cpu去執行指令對應具體操作的。所以cpu指令只能是二進制數據
哪裏可以看到二進制數據
可以用文本軟件打開exe,裏面就是二進制數據,但是一般文本軟件都是由16進制來顯示二進制數據的。因爲2進制很好用16進制來表示,4位2進制(0001)就能表示一位16進制。

二、cpu架構
cpu架構就是cpu芯片的硬件架構,也稱爲微架構,也就是一堆硬件電路,由這些硬件電路去實現cpu指令集所規定的操作運算,首先要明確 cpu指令集不是什麼具體的電路,而是一個規範,cpu架構就是實現這個規範實現,也可以說cpu芯片是這個規範的實例,所以說,cpu架構具體實現是可以不同的,但只要你這個cpu架構實現了某種指令集,你這個cpu就是這種指令集架構的cpu。以下舉個例子。
某個cpu芯片的硬件架構實現了某個cpu指令集,那麼這個cpu芯片就是什麼架構的cpu。舉個例子,某個cpu芯片的硬件架構實現了x86指令集,這個cpu芯片就是x86架構的cpu芯片,如果實現了mips指令集這個cpu芯片就是mips架構的cpu芯片
你可以理解爲,cpu指令集接口cpu架構接口實現類cpu芯片接口實現類的實例對象。

三、彙編語言
彙編語言就是用一些英文字符串來對照對應的cpu的指令集,一個彙編指令對應一個cpu指令也就是一些機器碼,彙編指令和cpu指令是互相對應的關係。僅此而己,沒有任何功能,只是起了一個助記作用,只是讓cpu指令集中的指令具有可讀性,而不是讓人類去閱讀cpu指令對應的機器碼
以下就是一張x86架構cpu的指令集
x86指令集資料
很清楚的看到一個彙編指令對應一個機器碼這個機器碼就是cpu指令,彙編指令就是起一個助記作用,只是換個方式來描述cpu指令。
彙編語言=cpu指令集
彙編指令=cpu指令=機器碼
數據=機器碼
彙編程序=彙編指令+數據=機器碼
在這裏插入圖片描述

四、交叉編譯
交叉編譯簡單描述就是,在當前的cpu架構上,使用另一個cpu架構做爲編譯規則編譯器程序,來編譯高級語言源代碼,從而生成另一個cpu架構可執行的機器碼。

詳細描述爲,就是在當前cpu中運行(編譯器機器碼轉化代碼文本機器碼生成爲cpu可執行機器碼)的過程中,不是根據當前cpu架構來生成cpu可執行機器碼,而是根據其它cpu架構來生成cpu機器碼,這種不以當前cpu架構來生成cpu機器碼編譯方式就是交叉編譯。

那爲什麼要用這種編譯方式
打個比方,你如果是用x86彙編寫的程序只能在使用x86架構的cpu上運行,在arm架構的cpu上是運行不了的,原因在於x86彙編本質上是x86cpu指令集,而x86架構的cpux86指令集進行了硬件實現,所以x86彙編寫的程序可以在x86架構的cpu上運行。但是arm架構的cpu 硬件實現的是arm指令集,不能識別x86彙編(x86指令集的指令,arm架構的cpu只能識別 arm彙編(arm指令集的指令,這時就可以用交叉編譯,生成另一個cpu架構的程序。

再說說現實中經常使用的編譯器程序吧。
gcc編譯器程序都聽過吧,默認的gcc是x86版本的,針對的是x86架構的cpu,但是gcc不只這一個x86版本的gcc,gcc還有arm-gcc,mips-gcc,分別針對arm架構的cpu和mips架構的cpu。gcc支持交叉編譯

五、高級語言/編譯器程序
高級語言只是一個語法規則高級語言只要有了編譯器程序能轉換爲機器碼,就可以用高級語言源代碼去寫語言語法解析邏輯,通過編譯器程序轉化爲程序後,去解析任何語言規則,當然包括上一代語言的語言規則。
高級語言的產生是爲了實現程序跨cpu架構複用,高級語言跨cpu架構原理通過高級語言對應的各個cpu架構的高級語言編譯器程序
高級語言編譯器程序簡單來說就是一個轉換高級語言語言規則cpu可執行機器碼一個程序

每個高級語言都有自己的高級語言編譯器程序高級語言源代碼需要通過高級語言編譯器程序編譯才能得到cpu指令二進制機器碼纔可以在cpu上運行。所以說,沒有編譯器程序高級語言進行解析編譯高級語言就是一個文本

高級語言的第一個編譯器程序從哪來?
兩個來源一個是基於彙編來寫編譯器程序,一種基於己實現編譯器程序另一個高級語言通過編譯另一個高級語言寫的高級語言編譯器源代碼得到編譯器程序,第一種用彙編寫的編譯器程序高級語言,就是第一代高級語言

有了第一代高級語言x編譯器彙編程序後,你就不僅只能使用彙編寫程序了,還可以使用第一代高級語言x來寫x語言源代碼然後通過編譯器彙編程序進行編譯來寫程序,你甚至還可以用x語言寫第二代高級語言y編譯器x語言代碼,只需要通過第一代高級語言x編譯器彙編程序第二代高級語言y語言編譯器x語言代碼進行編譯後,就得到了第二代高級語言y的編譯器程序,則代表第二代高級語言y就可以被cpu識別了,甚至可以把第二代高級語言y的語法第一代高級語言x的語法設置爲一樣語法,這樣也可以證明第一代高級語言x自舉的能力

舉個例子假設第一代高級語言c語言。有了第一個c語言編譯器彙編程序後,就可以使用c語言c++語言編譯器c語言源代碼(二進制文本),通過c語言編譯器彙編程序編譯c++語言編譯器c語言源代碼(二進制文本)後,得到一個c++編譯器程序(二進制可執行文件),通過這個c++編譯器程序c++語言源代碼二進制文本就能轉換成cpu可執行的機器碼了,有了這個c++編譯器程序,你就可以用c++語言在寫一個js語言編譯器c++源代碼,通過c++編譯器程序編譯後就得到時一個能編譯js語言二進制文本的的編譯器程序,有了js語言編譯器程序,你就可以用js語言在寫一個c語言編譯器程序js源代碼,通過js編譯器程序編譯js源代碼後就得到了能解析c語言語法規則c語言編譯器程序。當然語言代級過高,會有很多冗餘操作導致效率問題。

看個總結

//y是一個有編譯器的語言,x是一個沒編譯器的語言
y,x=rule
y  => yCompiler =>cpu code

//y寫了一個解析x語言的源代碼,並編譯成程序,這個程序就是x語言的編譯器 
y*x => yCompier => cpu code = xCompiler
x  => xCompiler =>cpu code

六、自舉
簡單來說,自舉就是用自身語言通過自身編寫的編譯器程序能夠編譯自身語言的源代碼
自舉其實是高級編程語言的一個能力
詳細點說就是x語言寫了個x語言編譯器x語言源代碼通過己有的x語言編譯器程序,編譯後得到新的x語言編譯器程序,這個新的x語言編譯器程序正常編譯x語言源代碼就代表這個編程語言自舉的能力

七、編譯和解釋
編譯型語言(c,c++),解釋型語言(php,js),混合型語言(java)都是高級編程語言,而高級編程語言只是一個包含邏輯的二進制文本要依靠編譯器程序進行編譯後才能得到cpu機器碼的。
解釋和編譯語言具體有什麼區別呢?
它們的區別在於語言的編譯器程序編譯源代碼方式不同
不同之處在於
簡單來說,就是編譯型語言全部代碼編譯完畢後,才能執行程序,解釋型語言是一邊編譯代碼,一邊執行程序
詳細來說,
編譯型語言的編譯器程序是把全部源代碼編譯爲機器碼後把機器碼存儲到一個新創建二進制文件裏,如果想要讓cpu運行源代碼程序就是執行編譯後生成的二進制文件。
解釋型語言的編譯器程序是在編譯源代碼爲機器碼的過程中當前編譯好的源代碼對應的機器碼直接讓cpu運行,解釋型語言編譯器程序,也叫解釋器程序解釋器程序一般都是守護進程一直運行在cpu中的。

八、cpu處理字符流程
那cpu不是隻處理二進制嗎?那它是怎麼處理文本的?下面舉個簡單的c程序例子
c程序編寫完c文件用ASCII編碼保存後,(能通過硬件編輯/顯示/保存文本是os的事,os一直在cpu上運行着一直幫你調度硬件呢)使其編譯成爲二進制機器碼後。在終端執行程序,會在終端窗口上輸出a,具體表現就是在屏幕上顯示a
這一具體的流程是什麼呢?你按下回車時,首先os會監聽到一個鍵盤輸入事件然後判段一些合法性問題os監聽的原理是一直監控着一個關於鍵盤輸入的文件,這個文件發生改變時,就會執行鍵盤輸入事件處理函數os判斷完後,就會調用cpu的驅動程序,然後cpu驅動程序就會調用cpu硬件接口把這些機器碼通過電流傳入到cpu芯片中。cpu芯片收到機器碼後就會執行機器碼,這些機器碼程序運行後做了以下這些事。
1.通知os在內存空間中存儲’a‘
要明確一個觀念os也是一個程序,一直運行在cpu。
首先會通過cpu自身的硬件接口調用os中的cpu驅動程序os通知內存條去存儲一個值爲97的二進制數字,具體怎麼通知內存的,流程跟調用cpu芯片一樣,這些硬件都是在主板上的,在硬件層面上是可以通信的。那爲什麼存儲97的二進制呢?由於代碼文本是用ascll字符編碼保存的在ascll字符編碼中碼值97對應的就是ascll字符集中的字符a,所以內存條存儲的就是97的二進制。還有個問題什麼是字符編碼字符編碼就是用數字碼值來對應指定字符集中的字符
打個比方說,想查看上面寫的c語言文本文件,就要用ascll字符編碼ascll字符集進行對應查找。
一個字符集可以對應多種字符編碼,如Unicode字符集就有 UTF-8,UTF-16 LE,UTF-16 BE 等字符編碼。當然,字符集中內容肯定是可以重複的。

2.通知os在終端屏幕上輸出’a’
在內存空間己經存儲好的’a‘,把值(97二進制)取出來後發送給os,發送原理就是通過驅動和硬件接口,os接收到值後查找ascll字符集找到編碼97對應字符a的點陣數據後,就會調用顯卡驅動程序,顯卡就將二進制數據信號轉換爲數字信號(也是二進制),然後通知os調用顯示器驅動程序,顯示器收到驅動程序傳來的數字信號轉換爲圖像信號並把圖像輸出到顯示器的像素點上,也就是屏幕終端上有一個a字符。
當然這是默認輸出,你也可以通過重定向輸出到文件裏。

#include <stdio.h>
int main(int argc, char *argv[])
{
	putchar('a');
	return 0;
}

cpu的好壞決定了程序處理速度,程序的數據是存在內存中的,程序即使沒有做任何cpu處理,但這個程序的數據還在內存中,就代表這個進程沒有銷燬。內存大程序運行的多,cpu好處理速度快。

說下計算機啓動流程,cpu首先加載主板bios操作系統程序主板bios操作系統程序根據啓動項設置去硬盤尋找用戶操作系統程序,再讀入內存,cpu執行內存中的用戶操作系統程序。所以說cpu,內存條,硬盤等這些硬件要對應適配的主板,不僅是硬件接口主板要支持,主板bios操作系統程序也要有對應的硬件驅動程序。

說下cpu讀取硬盤的操作流程,首先cpu發出指令,讓硬盤中存儲的二進制數據輸入給內存條,內存條把傳來的二進制數據進行寫入內存,然後輸出二進制數據給cpu進行運算。一個應用程序是運行狀態的,可能在cpu裏沒有運行處理,但內存中有這個程序的二進制數據和二進制代碼數據,就是運行狀態的應用程序。

一個應用程序,首先在cpu裏運行,然後運行結束後,把程序數據,也就是一些變量和代碼數據,存儲到內存條中,事件監聽交給操作系統,處理,根據事件監聽,調用不同的代碼數據,傳給cpu處理,又把程序數據存儲到內存條中。往往復復

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章