複製鏈接
請複製以下鏈接發送給好友

鏈接器

鎖定
鏈接器(Linker)是一個程序,將一個或多個由編譯器彙編器生成的目標文件外加庫鏈接為一個可執行文件。目標文件是包括機器碼和鏈接器可用信息的程序模塊。簡單的講,鏈接器的工作就是解析未定義的符號引用,將目標文件中的佔位符替換為符號的地址。鏈接器還要完成程序中各目標文件的地址空間的組織,這可能涉及重定位工作。
中文名
鏈接器
外文名
Linker
模    式
靜態鏈接動態鏈接
性    質
解析未定義的符號引用
全    稱
鏈接編輯器
產    生
可執行文件

鏈接器簡介

到目前為止我們描述的內容表明,對於源程序任意一行代碼的修改都需要重新編譯和彙編整個程序,全部重新翻譯是對計算資源的嚴重浪費。這種重複對於標準庫程序尤為浪費,因為程序員要編譯和彙編那些在定義上幾乎從未改變過的過程。另一種方法是單獨編譯和彙編每個過程,以使得某一行代碼的改變只需要編譯和彙編一個過程。這種方法需要一個新的系統程序,稱為鏈接編輯器(link editor)或鏈接器(linker),它把所有獨立彙編的機器語言程序“拼接”在一起。
鏈接器也稱鏈接編輯器,它是一個系統程序,把各個獨立彙編的機器語言程序組合起來,並且解決所有未定義的標記,最後生成可執行文件。

鏈接器鏈接器工作步驟

鏈接器的工作分3個步驟:
1、將代碼和數據模塊象徵性地放入內存。
2、決定數據和指令標籤的地址。
3、修補內部和外部引用。
鏈接器使用每個目標模塊中的重定位信息和符號表,來解析所有未定義標籤。這種引用發生在分支指令、跳轉指令和數據尋址處,所以這個程序的工作非常像一個編輯器:它尋找所有舊地址並用新地址取代它們:編輯是“鏈接編輯器”或鏈接器名字的簡稱。採用鏈接器的原因是修補代碼比重新編譯和彙編要快得多。
如果所有外部引用都解析完,鏈接器接着決定每個模塊將要佔用的內存位置。MlIPS在內存中為程序和數據分配空間的方式。因為文件是單獨彙編的,所以彙編器不可能知道該模塊的指令和數據相對於其他模塊而言將會被放到哪裏。當鏈接器將一個模塊放到內存中的時候,所有絕對引用(absolute reference),即與寄存器無關的內存地址必須重定位以反映它的真實地址。 [1] 
鏈接器產生一個可執行文件(executable file),它可以在一台計算機上運行。通常,這個文件與目標文件具有相同的格式,但是它不包含未解決的引用。具有部分鏈接的文件是可能的,如庫程序,在目標文件中仍含有未解決的地址。

鏈接器GNU鏈接器

GNU的鏈接器稱為ld,它負責把若干目標文件與若干庫文件鏈接起來,並重定位它們的數據位置。在編譯一個程序時,最後一步就是運行ld命令,通常ld直接由gcc負責調用,對用户程序員透明。ld能接受鏈接描述文件的控制,這是一種用鏈接命令語言(LinkerScript)寫成的控制文件,用來在鏈接的整個過程中提供顯式的、全局的控制。ld比其他鏈接器更有用的地方在於它提供了診斷信息。許多鏈接器在碰到錯誤的時候立即放棄執行,但ld卻能夠繼續執行,讓程序員發現其他的錯誤,或者在某些情況下,產生一個帶有錯誤信息的輸出文件。
如圖《鏈接器的作用》所示説明了ld的工作內容。對於多源文件程序,每個源文件被彙編為目標文件(Object File),鏈接器負責把這些目標文件,以及相關的庫文件鏈接到一起,形成可執行文件,這就是鏈接器的作用。
鏈接器的作用 鏈接器的作用
目標文件由若干段組成,包括代碼段、數據段和未初始化數據段等。鏈接時,ld將打破目標文件由若干段組成,包括代碼段、數據段和未初始化數據段等。鏈接時,ld將打破目標文件內部結構,把所有代碼段都提取出來,共同組成最終可執行程序的代碼段;把所有數據段提取出來,組成最終可執行程序的數據段;未初始化的數據段也做同樣操作。 [2] 
參考資料
  • 1.    帕特森.計算機組成與設計:機械工業出版社,2015
  • 2.    賴曉晨.嵌入式軟件設計:清華大學出版社,2016