編譯連線執行原理(C++ 和 linux gcc使用)

2020-08-13 12:38:58

C++

1.預編譯:

生成 .i檔案(高階語言)
①處理帶 # 的東西,刪除#define並做文字替換;
②遞回展開標頭檔案;
③處理#if #endif等預留編譯指令;
④刪除註釋,新增行號和檔案標識;
⑤保留#pragma指令。

2.編譯

生成 .s檔案(彙編語言)
①詞法分析(命名等規範否)
②語法分析(分析行表達式)
③語意分析(結合上下文)
④程式碼優化
⑤生成彙編指令

3.彙編

生成 .o檔案(目標檔案/可重入的二進制檔案)
翻譯指令(把低階語言翻譯成機器語言)
強弱符號(只針對於全域性變數)

強符號:已初始化的符號
弱符號:未初始化的符號

eg:

#include<stdio.h>
int a=10; //強符號
int b;//弱符號
int main()
{
printf("%d\n",a);
b=20;
}

4.鏈接

生成 .exe檔案
①合併段和符號表,處理強弱符號。
eg:合併:a.o b.o -----→ .exe
②外部符號處理,符號解析(在符號參照的地方找到符號定義的地方)
③處理虛假偏移和地址
④符號的重定位

5.執行

①建立虛擬地址空間和實體記憶體的對映,建立目錄和頁表
②載入指令和數據到記憶體上
③把程式入口地址放到下一個指令暫存器

linux

檔案:c→i→s→o
gcc使用:生成main可執行程式, ./main 執行
預編譯
gcc -e main.c -o main.i(生成.i檔案)
編譯
gcc -s main.i -o main.s(生成.s檔案)
彙編
gcc -c main.s -o main.o(生成.o檔案)
鏈接
gcc -o main main.o / gcc main.o -o main
(生成main可執行程式)
執行
./main

一般在編寫完程式碼後直接用
gcc -o main main.c(生成可執行程式)
(main.c是你編寫程式碼的.c檔案,名字可自取,可執行程式名字也可自取)