程式設計師的自我修養 動態鏈結(1)

2022-04-13 20:59:34 字數 1665 閱讀 7338

7.1為什麼要動態鏈結

用動態鏈結的原因是因為靜態鏈結有這樣那樣的問題。對比二者我們可以總結出靜態鏈結的倆大缺點,和動態鏈結的兩大優點:

(1)靜態鏈結浪費記憶體和磁碟空間

靜態鏈結會把所有鏈結到的庫裝載入記憶體,而卻這些庫裝載入記憶體後只能給程序自己使用,不能共享給別的程式程序使用。用書中的例子說,1個程式需要用100mb的記憶體,那麼100個程式就要用100mb,對空間的浪費很嚴重。

(2)程式的更新和公升級

書中的原話就是,程式中有任何模組更新,整個程式都需要更新重新鏈結,十分麻煩。

因此與此對立的就是動態鏈結庫的優點:

(1)當然是節省空間,同樣的庫只需存在乙份副本即可

(2)便於公升級,便於編寫外掛程式,便於跨平台使用(書上有例子)

7.2簡單的動態鏈結的例子

我覺得書上的圖7-3就可以說明乙個基本過程,不過書中讓我們需要知道的是為什麼鏈結器知道foobar函式是動態鏈結函式(即位址在裝載的時候才確定)。這是因為lib.so(動態共享物件)裡面有完整符號資訊,把lib.so作為鏈結之一,就會讓鏈結器知道這是乙個對動態物件的引用。

動態鏈結程式執行時位址空間的分布。

這個怎麼說呢?書中的意思,就是讓大家知道程式執行時這些庫已經被載入到記憶體了。。。

另外,還有個值得注意的地方就是,書中在本章的最後做了個示例,即共享物件在被程式載入之前,其裝載絕對位址是0x00000000。從這點就可以推斷共享物件的最終裝載位址在編譯時時是不確定的。。

7.3位址無關**

7.3.1固定裝載位址的困擾

哦。。。。他在這裡就是說實現動態鏈結庫需要面對的問題。7.3.1中指出的問題就是不同模組不能有同樣的裝載位址。一旦衝突了,就只能用其中之一,另乙個必須永遠放棄。這就是傳統的靜態共享庫,這種方式還會導致公升級很不方便。庫本身不能有太大的變化。

7.3.2裝載時重定位

gcc編譯共享庫時,如果不加上-fpic,則會採用動態共享庫的方式載入庫。但這種方式會產生另外乙個問題,就是不能被多個程序共享。以為裝載時重定位需要修改指令(call的位址不同)。

7.3.3位址無關**

首先先按書上說的分析模組中各種型別的位址引用方式。

第一種是模組內部的函式呼叫,跳轉。很簡單直接call

第二種時模組內部的資料訪問。利用i686.get_pc_thunk.cx來獲得下條指令的

位址,並存入ecx中。然後再加上偏移即可。

型別三模組間資料訪問。訪問存在於資料段段中的got(全域性偏移表)

型別四模組間呼叫,跳轉。訪問got,找到函式位址在got中的偏移,然後間接呼叫。

另外,書中還提了fpic和fpic的區別。fpic產生的**相對較小,速度快,但由於位址無關**都和硬體平台相關,不同的平台有不同的限制,所以為了方便起見大部分情況下我們都用fpic。

7.3.4 模組內部的全域性變數訪問

由於存在一種特殊的情況,比如:

extern int globle;

int foo()

此時編譯器無法判斷globle是模組間呼叫,還是模組內部呼叫。於是對他採用了類似於上述型別4的方法,即got段中的相應位址指向.bss中的副本。(還是有點漿糊.........)

7.3.5資料段位址無關性

對於共享物件來說,如果資料段中有對絕對位址的引用,那麼編譯器和鏈結器就會產生乙個重定位表,這個重定位表裡面包含了「r_386_relative」型別的重定位入口,用於解決上述問題。

程式設計師的自我修養(十)動態鏈結

動態鏈結其實就是把鏈結的過程推遲到了執行時再進行。特點 重定位位址無關 fpic與 fpie 模組內部的函式呼叫 跳轉等 這種不需要重定位 模組內部的資料訪問,比如模組中定義的全域性變數 靜態變數 相對定址 模組外部的函式呼叫 跳轉等 got,但是儲存的是目標函式的位址 模組外部的資料訪問,比如其他...

《程式設計師自我修養》閱讀筆記 動態鏈結

1 動態鏈結的含義。動態鏈結就是將鏈結時的重定位推遲到載入時。相比於靜態鏈結,動態鏈結的乙個優點是可以節省記憶體。因為共享檔案的 可以共享。使用動態鏈結的時候,可執行檔案和共享檔案都會載入到記憶體。但是,如果很多可執行檔案都使用了同乙個共享檔案的時候,共享檔案的 部分只需要裝載一次,這樣就達到了節省...

《程式設計師的自我修養》筆記 靜態鏈結

在通過編譯和彙編後,就生成了目標檔案,鏈結就是把這些目標檔案加工後合併成乙個輸出檔案的過程。鏈結過程可以分為兩步 第一步 空間與位址分配。掃瞄所有的輸入目標檔案,獲得它們每個各個段的長度 屬性和位置,並且將輸入目標檔案中的符號表中所有 的符號定義和符號引用收集起來,統一放到乙個全域性符號表。這一步中...