程式執行的過程是 編譯-彙編-鏈結成可執行檔案–通過裝載器把可以執行檔案裝載到記憶體中,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檔案並不新增到可執...