1. 程式人生 > >【C++】預編譯、編譯、彙編、連結

【C++】預編譯、編譯、彙編、連結

Windows中以2:2劃分核心、使用者空間,Linux中以1:3劃分核心、使用者空間。 

在text段中,只有普通區域性變數是指令 

int gdata1 = 10; //.data  已初始化且初始化不為零的資料
int gdata2 = 0;  //.bss   未初始化或初始化為零的資料
int gdata3;      //.bss
static int gdata4 = 20;  //.data
static int gdata5 = 0;   //.bss
static int gdata6;       //.bss
int main()
{
	int data1 = 30; //.text  //只有普通區域性變數是指令
	int data2 = 0;  //.text
	int data3;      //.text
	static int data4 = 40; //.data
	static int data5 = 0;  //.bss
	static int data6;      //.bss
	
	return 0;
}

預編譯:i

1.#define  巨集文字替換

2.#include  遞迴展開標頭檔案

3.#if #endif #elif  刪除預編譯指令

4.刪除註釋

5.新增行號和文字標識

6.保留 #pragma  編譯器處理

編譯:s  【編譯階段以一個.cpp或者.c檔案為單元編譯】

1.詞法分析

2.語法分析

3.語義分析

4.程式碼優化  生成彙編程式碼

[inter x86]  //彙編程式碼
int a = 10;
mov dword ptr[a],0Ah //ptr[a] 對a地址解引用後得到a的記憶體 //0Ah 是10

彙編:o  可重定位(重入)的二進位制檔案

  把指令程式碼翻譯成二進位制

  Linux中ELF檔案,bss段:段以符號起始,節省空間

  bss段少了一個數據,和虛擬地址空間上的段不同意義。 (bss段中少的資料,位於COM塊中)

  強弱符號:強符號是已初始化的全域性變數,弱符號是未初始化的全域性變數【C++中無強弱符號之分】

  強弱符號規則:

1.兩強:重定義錯誤  //資料段不可以出現重名

2.一強一弱:選強符號作為所有地址

3.兩弱:選位元組數大的   <編譯器處理>

在彙編完成前,不清楚是否存在強符號無法判斷時,則將變數放入COM塊中。

連結: 生成.exe檔案  也是ELF檔案,有頭和.data、.text段等

          //UND  未定義區  //找不到

1.段合併:相同段合併<一個段對映一個頁面> 

   合併符號表:同名查詢,未找到則用本身查詢的弱符號,找到則刪除弱符號改用強符號

2.符號解析(處理UND):未找到對應的符號進行報錯     合併UND

3.分配地址和空間

4.符號的重定位  //test段  <虛假地址改真實,糾正虛假偏移>

連結程式碼:[ld -e main -o run main.o sum.o]

【Linux】中關於預編譯、編譯、彙編、連結的程式碼

1.[預編譯] gcc  -E  Aff.c  -o  main.i

    [ls]  Aff.c   main.i

2.[編譯]gcc  -S  main.i  -o  main.s

    [ls]Aff.c   mian.i   main.s

3.[彙編]gcc  -C  mian.s  -o  main.o

    [ls]Aff.c   mian.i   main.s   main.o   a.out

4.[連結]/a.out    //此時是.exe檔案(可執行檔案)