天天看點

C語言編譯過程

C語言編譯過程

1.       預處理(Preproceessing)

預處理的過程主要處理包括以下過程:

  • 将所有的#define删除,并且展開所有的宏定義
  • 處理所有的條件預編譯指令,比如#if #ifdef #elif #else #endif等
  • 處理#include 預編譯指令,将被包含的檔案插入到該預編譯指令的位置。
  • 删除所有注釋 “//”和”/* */”.
  • 添加行号和檔案辨別,以便編譯時産生調試用的行号及編譯錯誤警告行号。
  • 保留所有的#pragma編譯器指令,因為編譯器需要使用它們

通常使用以下指令來進行預處理:

gcc -E hello.c -o hello.i

參數

-E

表示隻進行預處理 或者也可以使用以下指令完成預處理過程

cpp hello.c > hello.i      /*  cpp – The C Preprocessor  */

直接cat hello.i 你就可以看到預處理後的代碼

2.       編譯(Compilation)

編譯過程就是把預處理完的檔案進行一系列的詞法分析,文法分析,語義分析及優化後生成相應的彙編代碼。

$gcc –S hello.i –o hello.s

或者

$ /usr/lib/gcc/i486-linux-gnu/4.4/cc1 hello.c

注:現在版本的GCC把預處理和編譯兩個步驟合成一個步驟,用cc1工具來完成。gcc其實是背景程式的一些包裝,根據不同參數去調用其他的實際處理程式,比如:預編譯編譯程式cc1、彙編器as、連接配接器ld。

3.       彙編(Assembly)

彙編器是将彙編代碼轉變成機器可以執行的指令,每一個彙編語句幾乎都對應一條機器指令。彙編相對于編譯過程比較簡單,根據彙編指令和機器指令的對照表一一翻譯即可。

$ gcc –c hello.c –o hello.o

$ as hello.s –o hello.co

由于hello.o的内容為機器碼,不能以普通文本形式的檢視(vi 打開看到的是亂碼)。

4.       連結(Linking)

通過調用連結器ld來連結程式運作需要的一大堆目标檔案,以及所依賴的其它庫檔案,最後生成可執行檔案。

ld -static crt1.o crti.o crtbeginT.o hello.o -start-group -lgcc -lgcc_eh -lc-end-group crtend.o crtn.o (省略了檔案的路徑名)。

繼續閱讀