深入理解計算機系統03 程式的鏈結

2022-07-01 20:12:11 字數 3699 閱讀 2736

第三篇:程式的鏈結

高階語言出現之後,需要多人開發不同模組。

1) 確定符號引用關係

確定符號的定義

2) 合併相關.o檔案

同一位址空間,安排虛擬位址空間

3) 確定每個符號的位址

4) 在指令中填入新的位址

1. 模組化

2. 提高編譯效率和節省記憶體空間(共享庫的復用)

只需要重新編譯被修改的源程式檔案

分類:

3. 共享的目標檔案 linux中的.so,可動態裝入記憶體。windows 下共享庫檔案 .dll

重點:區分可重定位目標檔案和可執行目標檔案,elf

以 linux 為例

//每個模組有**和資料(初始化/未初始化全域性變數,靜態變數、區域性變數)

gcc -o2 -g

將不同可重定位目標檔案中的

.text

.data

.bss

分類合併,得到可執行檔案。

可執行檔案儲存映像

合併到虛擬位址空間(並非記憶體)

目標檔案的格式:

目標**

目標檔案

.bss 未初始化的全域性變數和區域性靜態變數

.data 已經初始化的全域性變數和區域性靜態變數

節是elf檔案中具有相同特徵的最小可處理單位。

從兩種角度來看:

1. 鏈結檢視——可重定位目標檔案

elf

.bss節不佔據磁碟空間,不須記錄初始值,只宣告佔據的記憶體空間

elf 頭:

分為64位和32位版本

頭資訊:最先的四個位元組是魔數

讀取方式 readelf -h main.o

elf 節頭表:

記錄每乙個節的起始位置,大小,對齊方式進行記錄。

32位的表項每個大小為40b

有四個節會分配儲存空間

.text

.data

.bss

.rodata (read only data)

2016-09-14

2. elf執行檢視——可執行檔案格式

重點:elf頭程式頭表:表述節和段之間的關係

可執行檔案的儲存器對映:

通過乙個實驗來了解符號解析:

生成乙個可執行檔案時,要進行符號解析,因而需要有符號表來確定包含在程式模組中的被定義的所有符號。

>>符號表:

符號有三種型別:

1. 全域性符號:被其他模組引用的非靜態全域性變數名。

2. 外部符號:在其他模組中定義的外部函式名和外部變數名。

3. 本地符號:static函式和全域性變數名。

>>符號解析:

1. 全域性符號的強弱型

已初始化的全域性變數名是強符號,未初始化的全域性變數名是弱符號。

規則:1. 強符號重複定義鏈結會起衝突。

2. 強定義遇到弱定義,服從強符號定義

3. 若有多個若符號定義,則任選其一。

實驗一:

#include

int x=10;

void p1(void);

int main()

int x;

void p1()

> gcc -o test main.o test.o

> ./test

x=200

實驗二:

#include

int x=10;

void p1(void);

int main()

char x;

void p1()

$ gcc -o test main.o test.o

$ ./test

x=120

x size is 4

'x' ascii = 120

size of char is 1

解說:強弱立見。

另外:

printf("%d",sizeof('a'));

在這裡輸出結果是4,因為 'a',會先轉化為對應 ascii 96,作為乙個 int,大小就變成4了。可以先宣告乙個變數char,sizeof(char) 還是 1;

>> 與靜態庫的鏈結

生成的可執行檔案能直接載入到儲存器執行,不需要在載入或者執行時再動態鏈結其他模組。

重定位:在符號解析的基礎上將所有關聯的目標模組合併,並確定執行時每個定義符號在虛擬位址空間中的位址,在定義符號的引用處重定位引用的位址。

節和定義符號的重定位,還有對於引用的符號,要去溯源。

重定位資訊:見 .rel.text節和 .rel.data節

重定位過程:略

調出載入器,根據可執行目標檔案中的程式頭表資訊,將可執行目標檔案中的相關節的內容與虛擬位址空間中的唯讀**段和可讀寫資料段通過頁表建立對映,然後啟動可執行目標檔案中的第一條指令執行。

連續的唯讀**段和可讀寫資料段,是的載入器對連續區域分頁和初始化變得簡單。

載入時,唯讀**段和可讀寫資料段對應頁表初始化為未快取頁(涉及到作業系統和組成原理知識),指向磁碟上目標檔案中某個地方。所以,程式載入過程中,並沒有真正從磁碟上載入**和資料到主存,只是建立了相應的頁表項。在執行**的過程中發生缺頁,才會從磁碟中載入**和資料。

關鍵技術:虛擬儲存管理

共享庫,『共享』『動態』

載入器:乙個作業系統

動態鏈結器

靜態鏈結

動態鏈結

1. 可重定位目標檔案

2. 可執行目標檔案

3. 共享目標檔案

兩種elf目標檔案格式:

2. 執行檢視:可執行目標檔案格式

1. 符號解析:將符號引用同定義關聯起來。

這裡主要用到的工具:

objdump

readelf –elf 顯示重定位

深入理解計算機系統

關鍵路徑是在迴圈的反覆執行中形成的資料相關鏈。迴圈展開是一種程式變換,通過增加每次迭代計算的元素的數量,減少迴圈的迭代次數。重新結合變換能夠減少計算中關鍵路徑上操作的數量,通過更好地利用功能單元的流水線能力得到更好的效能。浮點運算不保證是可結合的,通常迴圈展開和並行地累積在多個值中,是提高程式效能的...

《深入理解計算機系統》

知乎 深入理解計算機系統 這本書需要什麼水平能看懂?15 213 18 218 15 513 introduction to computer systems schedule fall 2016 鏈結失效則 cmu15 213的課程主頁,有ppt,還有錄影,主講人就是這本書的作者。備註 備註 詳細...

深入理解計算機系統

系統的硬體組成 快取記憶體 作業系統管理硬體 程序虛擬記憶體 檔案amdahl定律 併發和並行 0和1組成的位序列,又稱為位元序列,8個位被組織成一組,成為位元組。每個位元組表示程式中的某些文字字元。系統中的所有資訊 包括磁碟檔案 記憶體中的程式 記憶體中存放的的使用者資料以及網路上傳送的資料,都是...