編譯鏈結原理

2021-08-31 13:28:13 字數 1500 閱讀 4611

32位計算機,每個程式都有4g的虛擬位址空間。首先虛擬位址空間分為兩大塊,乙個是使用者空間,乙個是核心空間。使用者空間佔3g的大小,並且它是每個程序所獨有的,它的開頭128m存放的是我們無法訪問的地方。

1、預編譯(生成 .i 檔案)

操作命令:gcc -e main.c -o main.i

具體內容:

(1)巨集定義指令

(2)條件編譯

(3)標頭檔案包含指令

(4)特殊符號處理

常見問題:

不能在標頭檔案中定義全域性變數,因為在標頭檔案中定義全域性變數將會使所有包含該標頭檔案的檔案存在該段**,也就是說這些檔案將定義乙個相同的全域性變數,這樣將不可避免的造成衝突 

2、編譯(生成 .s 檔案,即彙編檔案)

操作命令:gcc -s main.i -o main.s

具體內容:編譯環節是指對源**進行語法分析,並優化產生對應的彙編**的過程

(1)    生成符號

(2)    生成彙編指令

3、彙編(生成 .o 檔案,即二進位制可重定位檔案)

操作命令:gcc -c main.s -o main.o

具體內容:將組合語言翻譯成機器語言(二進位制)**

注意:

因為.bss段中的資料都是沒有初始化或初始化為0的資料,所以每個數的值都為0,沒必要每個都儲存,只需要標識其存在即可。每個資料都會生符號,.bss段的大小只是說明有多少個資料(弱符號不計入其中),並不實際儲存,而實際的資料產生的符號在符號表中。這樣就解決了資料的標識問題。

強符號:初始化了的非靜態資料

弱符號:沒有初始化的非靜態資料

弱符號不往資料段儲存(指的是不參與.bss段對資料個數的計算),只會產生乙個/*com*標誌

操作命令:gcc -o main main.s

具體內容:將有關的目標檔案彼此鏈結,也即將在乙個檔案中引用的符號同該符號在另外乙個檔案中的定義鏈結起來,是的所有的這些檔案成為乙個能夠讓作業系統裝入執行的統一整體,可分為動態鏈結和靜態鏈結

鏈結有以下幾個部分要做:

1、 合併段表:將多個二進位制可重定位檔案中的段資訊整合放到乙個檔案中

2、 調整段偏移:段表經過合併之後大小發生了變化,所以位址需要適當的偏移

3、 合併符號表:將多個二進位制可重定位檔案中的符號整合到乙個檔案中

4、 完成符號的重定位:聯結器把每個符號定義與乙個虛擬位址聯絡起來,然後修改所有對這些符號的引用,使得它們指向這個儲存位置,從而重定位這些節。

按照不同段的屬性相同的不同的段劃分到同一頁裝入虛擬位址空間

32位虛擬位址空間是多大?為啥?

4g,32位指的是位址匯流排的條數 32條,2^32 = 4g

編譯鏈結原理

從源 到可執行程式,需要經歷以下幾個過程 預處理 編譯 彙編 連線。1.預處理 預處理主要是處理以 開頭的預編譯指令,包括 include define if等 刪除注釋 新增行號以及標頭檔案展開。2.編譯 編譯的主要工作是詞法分析 語法分析 優化編譯,將源 翻譯成彙編 3.彙編 彙編是將彙編 翻譯...

編譯鏈結原理

32位計算機,每個程式都有4g的虛擬位址空間。首先虛擬位址空間分為兩大塊,乙個是使用者空間,乙個是核心空間。使用者空間佔3g的大小,並且它是每個程序所獨有的,它的開頭128m存放的是我們無法訪問的地方。text c語言的編譯後執行語句都編譯成機器 儲存在.text段 data 已初始化的全域性變數和...

編譯鏈結原理

1.預編譯階段 生成.i檔案 1 刪除 define,並展開所有的巨集進行文字替換 2 遞迴展開 include 3 處理所有條件預編譯指令,如 if endif ifdel等 4 刪除注釋 5 新增行號和檔名標識 6 保留所有的 pragma編譯器指令,待編譯器使用 2.編譯階段 生成.s檔案 把...