《連接器與加載器》——第一章 連接和加載

連接器負責的工做:ios

  地址綁定、重定位、庫查詢、代碼分段函數

加載器負責的工做:blog

  重定位(先因爲硬件重定位而省略)內存

 

地址綁定:字符串

  將更抽象的名字與更底層的名字綁定(如getline名字綁定到iosys模塊內可執行代碼的612字節處,或這個模塊靜態數據開始的第405字節處)。get

重定位:編譯器

  編譯器和彙編器生成的目標代碼地址從0開始。一個程序有多個子程序組成,子程序們的地址不能重疊。重定位就是爲程序不一樣部分分配加載地址,調整程序中的數據和代碼以反映所分配地址的過程。數學

  重定位通常不止一次,連接時,各子程序經過重定位在大程序中肯定位置。當程序加載時,系統會選擇一個加載地址,而連接好的程序會做爲總體被重定位到加載地址。io

符號解析:編譯

  當多個子程序構建一個大程序時,子程序間互相做用是經過符號進行的,如主程序調用sqrt,sqrt定義在數學庫中。連接器經過標明分配給sqrt的地址來解析這個符號,並修改目標代碼使得call指令引用該地址。

程序加載:

  將程序從輔助存儲器拷貝到內存中,準備運行。有些狀況下,還包括分配存儲空間,設置保護位,或經過虛擬內存將虛擬地址映射到磁盤內存頁上。

  當容許一個程序的多個實例時,程序中的某些部分在全部的容許實例中都是相同的(尤爲時可執行代碼),而另外一些部分是各實例獨有的。

 

編譯連接實例

 

m.c

m包含程序段16B,數據段16B(字符串)

符號表:_main(導出符號)、_a(導入符號)

程序先將字符串的地址壓棧,用於傳參。

在調用a函數時,因爲a未知,因此用0x0代替地址,並作好標記。

 

a.c

a.c程序段0x1c字節

其中調用的庫函數都是未知的因此用0x0代替入口地址

使用靜態連接

連接後數據段變多,是因爲使用靜態連接庫函數

程序增長了啓動代碼start-c,和調用的庫函數例程

_c和_main符號都從新進行地址綁定。

能夠看出靜態連接會複製導入的符號相關的實例,這就形成了程序體積會很大

相關文章
相關標籤/搜索