預處理,編譯,彙編和鏈接

當我們gcc 編譯一個程序的時候有沒有想過到底發生了什麼?

1、我們有一個hello.c文件,用最簡單的命令gcc hello.c 生成 a.out 這個過程可以分爲四個步驟:預處理(Prepressing)、編譯(Compilation)、彙編(Assembly)和鏈接(Linking)。

一、預編譯 

1.將所有的#define刪除,並展開所有的宏定義; 

2.處理所有的預編譯指令,例如:#if,#elif,#else,#endif; 

3.處理#include預編譯指令,將被包含的文件插入到預編譯指令的位置; 

4.添加行號信息文件名信息,便於調試; 

5.刪除所有的註釋:// /**/; 

6.保留所有的#pragma編譯指令,因爲在編寫程序的時候,我們經常要用到#pragma指令來設定編譯器的狀態或者是指示編譯器完成一些特定的動作。 

gcc -E  hello.c -o hello.i

二、編譯

編譯主要是將高級語言生成彙編語言

1.掃描,語法分析,語義分析,源代碼優化,目標代碼生成,目標代碼優化;

2.生成彙編代碼;

3.彙總符號; 

4.生成.s文件

gcc -S hello.i -o hello.s

三、彙編

彙編過程是將彙編語言轉變爲機器可以執行的機器語言,每個彙編語句幾乎對應着一條機器指令。

1.根據彙編指令和特定平臺,把彙編指令翻譯成二進制形式;

2.合併各個section,合併符號表; 

3.生成.o目標文件。

gcc -c hello.s -o hello.o 

四、鏈接

1.合併各個.obj文件的section,合併符號表,進行符號解析; 

2.符號地址重定位; 

3.生成可執行文件。