GCC 將 C 源文件轉換為可執行文件經歷四個階段:
.i.s.oouthello.c#include <stdio.h>
int main() {
printf("happy new year!\n");
return 0;
}
-Egcc -E hello.c -o hello.i
hello.i 包含 <stdio.h> 全文展開、宏 printf 替換、條件編譯處理後的純 C 代碼,無 # 指令。
-Sgcc -S hello.i -o hello.s
hello.s 為 AT&T 風格匯編代碼,可見 call printf、棧幀建立/銷毀指令。
-cgcc -c hello.s -o hello.o
hello.o 為 ELF 可重定位目標文件,包含機器碼、符號表、重定位表。使用 objdump -d hello.o 可查看反匯編。
gcc hello.o -o hello
鏈接器 ld 將 hello.o 與 C 庫(libc、crt1.o 等)合併,解析 printf 等外部符號,生成最終可執行文件 hello。
gcc hello.c -o hello
內部自動完成上述四步,刪除中間文件。調試時可保留中間產物:
gcc -save-temps hello.c -o hello # 保留 .i .s .o
| 參數 | 作用 | 輸出 |
|---|---|---|
-E | 僅預處理 | .i |
-S | 編譯至匯編 | .s |
-c | 編譯+匯編,不鏈接 | .o |
-o file | 指定輸出文件名 | 任意 |
-v | 顯示編譯器調用的詳細子命令 | 控制台 |
-### | 僅打印子命令不執行 | 控制台 |
掌握 GCC 四階段流程,能將「編譯報錯」從黑盒變為白盒,快速定位構建問題,也是理解鏈接器腳本、動態庫加載、啟動流程的基石。