第三篇:程式的鏈結
高階語言出現之後,需要多人開發不同模組。
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個位被組織成一組,成為位元組。每個位元組表示程式中的某些文字字元。系統中的所有資訊 包括磁碟檔案 記憶體中的程式 記憶體中存放的的使用者資料以及網路上傳送的資料,都是...