我們都知道,」hello world「 程式是程式設計師的啟蒙語句,它的編譯過程一氣呵成,但是它的具體編譯過程是什麼呢?在編譯果程中做了什麼?
在linux下,當我們使用gcc來編譯「hello world」程式時,只需使用最簡單的命令(假設源**檔名為hello.c):
$ gcc hello.c ; $ ./a.out ;
事實上,上述過程分為四個步驟,分別是預處理(prepressing),編譯(compliation),彙編 (assembly)和鏈結(linking),如圖所示
1. 預編譯
預編譯過程主要處理那些以源**檔案中的以「 # 」開始的預編譯指令,經過編譯後的檔案為 .i 檔案。主要處理規則如下:
(1)處理所有的條件編譯指令,比如 「 #if 」,「 #ifdef " , " #ifndef " , " #endif " , " #else " 等。
(2)處理」#include 「 預編譯指令,將包含的檔案插入到該預編譯指令的位置。
(3)將所有的」#define 「所定義的巨集進行巨集替換。
(4)刪除所有的注釋 」//「和」/* */「。
(5)新增行號和檔名標識,以便於編譯時編譯器產生除錯用的行號資訊 及 用於編譯時產生的編譯錯誤或警告時能夠顯示行號。
(6)保留所有的 #pragma 編譯器指令。
2. 編譯
編譯過程就是對預處理後的檔案進行 詞法分析,語法分析,語義分析 及 優化後產生相應的彙編**檔案。
相當於命令$ gcc -s hello.i -o hello.s
產生的檔案為.s 檔案。
(1)詞法分析
將源**的字串行分割成一系列的記號。詞法分析所產生的記號一般分為如下幾類:關鍵字,識別符號,字面量和特殊符號,將所對應的符號放入符號表中。
(2)語法分析
語法分析器將對產生的記號進行語法分析,從而產生語法樹,即以表示式為結點的樹。在語法分析階段對一些內容進行區分,如果表示式不合法,編譯器就會報出錯誤。
(3)語義分析
對語法樹的表示式標識型別 。
3. 彙編
將彙編**變成機器可以執行的指令,每乙個彙編語句對應一條機器指令。它沒有複雜的語法,也不需要做指令優化。
相當於命令$ gcc -c hello.s -o hello.o;
此時生成目標檔案,即 .o 檔案。
4. 鏈結
gcc編譯過程
本文對gcc編譯器如何工作做乙個概要描述.更為詳細的資訊請參考編譯器手冊。當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。...
gcc編譯過程
當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。gcc將c檔案編譯成彙編檔案。3 彙編。as將彙編檔案編譯成機器碼。4 連...
GCC編譯過程
第一步 預處理後結束 引數 e gcc e hello.c o hello.i 檢視hello.i檔案中的內容 cat hello.i stdio.h的內容插入到檔案裡去了,巨集定義也在預處理中都做了相應的處理 第二步 將hello.i 編譯為 目標 引數 c gcc c hello.i o hel...