gcc 編譯過程

2022-08-24 13:51:11 字數 3433 閱讀 7634

gcc編譯過程

從 hello.c

到 hello(

或 a.out)

檔案, 必須歷經 hello.i

、 hello.s

、 hello.o

,最後才得到 hello(

或a.out)

檔案,分別對應著預處理、編譯、彙編和鏈結 4

個步驟,整個過程如圖 10.5

所示。

這 4

步大致的工作內容如下:

(1) 預處理, c

編譯器對各種預處理命令進行處理,包括標頭檔案包含、巨集定義的擴

展、條件編譯的選擇等;

(2) 編譯,將預處理得到的源**檔案,進行「翻譯轉換」,產生出機器語言的目標

程式,得到機器語言的彙編檔案;

(3) 彙編,將彙編**翻譯成了機器碼,但是還不可以執行;(4

下面根據 hello.c

這個示例,跟蹤一下其中的細節。

1)預處理

在 gcc

命令加上-e

引數,可以得到預處理檔案。輸入下列命令:

vmuser@linux-host:hello$ gcc -e hello.c –o hello.i

將會產生 hello.i

檔案,這就是 hello.c

經過預處理後的檔案。實際操作結果見圖 10.6

圖 10.6

預編譯得到

hello.i

檔案乙個原本連同空行才 8

行的**,經過預處理,得到了乙個 800

多行的預處理檔案,文

件開的內容如圖 10.7

所示。

圖 10.7 hello.i

檔案開頭

hello.i

檔案末尾處的內容如圖 10.8

所示。

圖 10.8 hello.i

檔案末尾

其餘部分內容請用 vi

開啟後進行檢視。可以看到, hello.c

經過預處理後得到的 hello.i

檔案,除了原本的幾行**之外,還包含了很多額外的變數、函式等等,這些都是預處理器

處理的結果。

2)編譯

在 gcc

編譯引數加上-s

,可以將 hello.i

編譯成 hello.s

檔案。命令如下:

vmuser@linux-host:hello$ gcc -s hello.i

實際操作和結果如圖 10.9

所示。圖 10.9

編譯得到

hello.s

檔案hello.s

是乙個彙編檔案,可用 vi

編輯器開啟檢視,如圖 10.10

所示。

圖 10.10 hello.s

檔案內容

可以看到,該檔案內容都是彙編語句。這裡不對彙編進行解釋。

3)彙編

得到了彙編檔案後,通過 gcc

就可以得到機器碼了。在終端輸入下列命令,可以得到

hello.o

檔案。vmuser@linux-host:hello$ gcc -c hello.s

實際操作和結果如圖 10.11

所示。

圖 10.11

彙編得到

hello.o

檔案(4)鏈結

儘管已經得到了機器碼,但這個檔案卻還是不可以執行的,必須要經過鏈結才能執行。

在終端輸入下列命令,將會得到可執行檔案 a.out

。vmuser@linux-host:hello$ gcc hello.o

操作和結果如圖 10.12

所示。

圖 10.12

鏈結得到

a.out

檔案a.out

是 gcc

預設輸出檔名稱,可以通過-o

引數指定新的檔名。例如加上「-o hello

」引數,將會生成 hello

檔案,這個檔案和 a.out

實際上是一樣的,用 md5sum

命令計算檔案校

驗值,兩者完全一樣,如圖 10.13

所示。

圖 10.13 a.out

和 hello

檔案動態鏈結使用動態鏈結庫進行鏈結,生成的程式在執行的時候需要載入所需的動態

庫才能執行。動態鏈結生成的程式小巧,但是必須依賴動態庫,否則無法執行。

 linux 下的動態鏈結庫實際是共享目標檔案(shared object),一般是.so 檔案,

作用類似於 windows 下的.dll 檔案。

 靜態鏈結使用靜態庫進行鏈結,生成的程式包含程式執行所需要的全部庫,可以直

接執行,不過體積較大。

 linux 下靜態庫是彙編產生的.o 檔案的集合,一般以.a 檔案形式出現。

gcc

預設是動態鏈結,加上-static

引數則採用靜態鏈結。再來看 hello.c

示例,在鏈結的

時候加上-static

引數:vmuser@linux-host:hello$ gcc hello.o -static -o hello_static

操作命令和結果如圖 10.14

所示,可以看到,動態鏈結生成的檔案大小是 7155

位元組,而靜態鏈結生成的檔案卻有 616096

位元組,體積明顯大了很多。

圖 10.14

靜態鏈結和動態鏈結結果對比

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...