本文對gcc編譯器如何工作做乙個概要描述.更為詳細的資訊請參考編譯器手冊。
當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括:預處理器cpp,編譯器前端gcc/g++,彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段:
(1)預處理。預處理器cpp將對原始檔中的巨集進行展開。
(2)編譯。gcc將c檔案編譯成彙編檔案。
(3)彙編。as將彙編檔案編譯成機器碼。
(4)連線。ld將目標檔案和外部符號進行連線,得到乙個可執行二進位制檔案。
下面以乙個很簡單的test.c來**這個過程。
#definenumber(1+2)
int main()
(1)預處理:
gcc會首先呼叫cpp進行預處理:cpp test.c > test.i
預處理的輸出為檔案test.i。
我們用cat test.i檢視test.i的內容如下:
int main()
我們可以看到,檔案中巨集定義number出現的位置被(1+2)替換掉了,其它的內容保持不變。
(2)gcc將c檔案編譯成彙編檔案。
接下來gcc會執行gcc -s test.i得到的輸出檔案為test.s.
(3)as將彙編檔案編譯成機器碼。
as test.s -o test.o
得到輸出檔案為test.o.
test.o中為目標機器上的二進位制檔案.
用nm檢視檔案中的符號:nm test.o
輸出如下:
00000000 b .bss
00000000 d .data
00000000 t .text
u ___main
u __alloca
00000000 t _main
既然已經是二進位制目標檔案了,能不能執行呢?試一下./test.o,提示cannot execute binaryfile.
原來___main前面的u表示這個符號的位址還沒有定下來,t表示這個符號屬於**段。ld連線的時候會為這些帶u的符號確定位址。
(4)連線。
連線需要指定庫的位置。通常程式中會有很多的外部符號,因此需要指定的位置就會很多。
不過,我們之需要呼叫gcc即可,ld會自己去找這些庫的位置。
gcc test.o > test
就得到了最終的可執行程式了。
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...