程式裝載及靜態動態鏈結

2021-10-23 03:29:01 字數 1301 閱讀 8675

程式執行的過程是 編譯-彙編-鏈結成可執行檔案–通過裝載器把可以執行檔案裝載到記憶體中,cpu從記憶體中讀取裝載器裝入的指令和資料。

裝載器把指令和資料裝載到記憶體需要滿足兩個要求:

找出一塊物理記憶體和虛擬記憶體進行對映的方法叫做分段。但是分段會產生記憶體碎片

比如1gb記憶體分配了512mb 128mb 256mb 128mb的記憶體,這時候兩個128mb的資源釋放了,但是這兩個記憶體不是連續的如果遇到乙個需要129mb記憶體的程式就無法載入進來。

處理辦法用了記憶體交換

用了交換區來作為中介,把256mb的程式先放入交換區,然後再載入回來,把碎片空間連線在一起。

記憶體分段雖然解決了記憶體碎片的問題,但是每次記憶體交換非常耗時。

現在計算機的記憶體管理裡面常用記憶體分頁

分頁的思想就是把原來一大段的記憶體,細分下去,分成固定長度的一小段一小段。之後虛擬記憶體到物理記憶體的對映也根據分頁來做了。

當系統啟動時,可能有非常多的程式需要通過裝載器把資料和**裝載到記憶體中,而且又很多程式會用到相同的資料和**,如果每次都裝載那非常消耗記憶體。因此就需要用鏈結的方式來達到**的復用。

靜態鏈結庫

鏈結器從靜態鏈結庫lib獲取所有被引用函式,並將庫同**一起放到可執行檔案中,應該就是編譯的時候就把所有的資訊都加入。 就是非常消耗記憶體的方式。

動態鏈結庫

允許可執行模組(.dll檔案或.exe檔案)僅包含在執行時定位dll中函式的可執行**所需的資訊。

動態鏈結庫實現了**在開發階段的復用和執行階段的復用

顯式呼叫動態庫步驟:

1、建立乙個函式指標,其指標資料型別要與呼叫的 dll 引出函式相吻合。

2、通過 win32 api 函式loadlibrary()顯式的呼叫dll,此函式返回dll 的例項控制代碼。

3、通過 win32 api 函式getprocaddress()獲取要呼叫的dll 的函式位址,把結果賦給自定義函式的指標型別。

4、使用函式指標來呼叫 dll 函式。

5、最後呼叫完成後,通過 win32 api 函式freelibrary()釋放dll 函式。

常稱為堆疊幀或者活動記錄,一般包含:

函式返回位址和引數

臨時變數:包含函式非靜態區域性變數和編譯器生成的臨時變數等

保留上下文:包括函式前後呼叫需要保持不變的暫存器

分配演算法:空閒鍊錶 位圖 物件池

靜態程式編譯鏈結與裝載

linkers and loaders 中文版 英文版 elf檔案格式 c語言編譯過程詳解,預處理,編譯,彙編,鏈結 乾貨滿滿 靜態程式編譯鏈結與裝載 一 問題的引入以及工具介紹 靜態程式編譯鏈結與裝載 二 編譯鏈結以及elf中section詳細分析 靜態程式編譯鏈結與裝載 三 segment分析以...

程式鏈結與裝載

程式的執行需要執行環境支撐,其執行環境一般由記憶體 執行庫和系統呼叫構成。其中系統呼叫部分程度上充當的是程式與核心進行互動的中介。其中首先需明白,程式與記憶體關係。記憶體是承載程式執行的介質,也是程式進行各種運算和表達的場所。window在預設情況下會將高位址的 2g 空間分配給核心 4g記憶體情況...

動態鏈結 靜態鏈結

在linux系統中,ld鏈結器將彙編器編譯出來的目標檔案和靜態庫里的.a檔案鏈結生成可執行檔案。靜態庫中的.a檔案的 會在靜態鏈結過程中新增到可執行檔案中,可執行檔案會變得很大。與靜態鏈結不同,linux系統的ld鏈結器會將動態庫.so檔案進行符號重定位生成可執行檔案,動態庫.so檔案並不新增到可執...