首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

GCC 編譯 C 程序的四個階段詳解:預處理、編譯、匯編、鏈接

     編輯:關於C語言

編譯流程總覽

GCC 將 C 源文件轉換為可執行文件經歷四個階段:

  1. 預處理:展開頭文件、宏替換、條件編譯 → .i
  2. 編譯:詞法/語法/語義分析,生成匯編代碼 → .s
  3. 匯編:匯編語言翻譯為機器指令,產生目標文件 → .o
  4. 鏈接:合併多個目標文件與庫,解析符號引用,生成可執行文件 → out

實戰演示:hello.c

#include <stdio.h>
int main() {
    printf("happy new year!\n");
    return 0;
}

1. 預處理 -E

gcc -E hello.c -o hello.i

hello.i 包含 <stdio.h> 全文展開、宏 printf 替換、條件編譯處理後的純 C 代碼,無 # 指令。

2. 編譯 -S

gcc -S hello.i -o hello.s

hello.s 為 AT&T 風格匯編代碼,可見 call printf、棧幀建立/銷毀指令。

3. 匯編 -c

gcc -c hello.s -o hello.o

hello.o 為 ELF 可重定位目標文件,包含機器碼、符號表、重定位表。使用 objdump -d hello.o 可查看反匯編。

4. 鏈接

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 四階段流程,能將「編譯報錯」從黑盒變為白盒,快速定位構建問題,也是理解鏈接器腳本、動態庫加載、啟動流程的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved