20135239 益西拉姆 深刻理解計算機系統 之複習第七章

chapter7 連接

概述

  • 定義:連接是將各類數據和代碼收集起來成並組合成爲一個單一文件的過程(這個文件能夠被拷貝到存儲器而且執行)
  • 場合:函數

    編譯時:即源代碼被翻譯成機器代碼
    加載時:程序被加載器加載到存儲器並執行
    運行時
  • 做用:翻譯

    使得分離編譯成爲可能(將大型應用程序分解爲若干個小模塊)

7.1 編譯器驅動程序--7.5 符號和符號表

編譯驅動程序表明用戶調用語言預處理器、編譯器、彙編器和連接器 1. 預處理器將.c文件翻譯成ASCII碼中間文件.i 2. 編譯器將.i文件翻譯成ASCII碼彙編語言文件.s 3. 彙編器將.s文件翻譯成可重定位目標文件.o 4. 連接器程序將.o文件以及一些必要的文件組合起來建立一個可執行目標文件 5. 加載器拷貝可執行文件代碼和數據到存儲器而後將控制轉移到程序頭3d

  1. 目標文件的三種格式:code

    1. 可重定位目標文件blog

      • 包括:
        • ELF頭:描述文件系統的字的大小和字節順序,ELF頭的大小,目標文件類型,機器類型等
        • 節:.text已編譯程序的機器代碼,.data&.bss分別是已初始化和未初始化的變量,.symtab一個符號表存放在程序中定義和引用的全局變量信息
        • 符號表中三種不一樣的符號: 由本模塊定義並被其餘模塊引用的全局符號(即不帶static的全局變量) 由其餘模塊定義並被本模塊引用的全局符號(即定義在其餘模塊中的C函數變量) 只被本模塊定義和引用的本地符號 另外,本地程序非靜態變量不在符號表中,它們在運行時在棧中被管理;編譯器把初始化爲0的變量放在.bss而非.data中
      • 節頭部表:描述目標文件的節

      2.可執行目標文件編譯器

      - ELF頭部:描述整體格式,包括程序的入口點也就是程序運行的時候要執行的第一條指令
      -  段頭部表:描述可執行文件連續片和存儲器段的映射關係
      - 其餘

    3.共享目標文件(特殊的可重定位目標文件)博客

靜態連接

  • 連接器的兩個主要任務編譯

    -符號解析:將每一個符號引用恰好和一個符號定義聯繫起來
    - 重定位:連接器經過把每一個符號定義與一個存儲器位置聯繫起來

7.6符號解析

  • 對於那些和引用定義在相同模塊的本地符號;編譯器只容許每一個模塊中每一個本地符號有一個定義
  • 對於全局符號的解析變量

    • 當編譯器遇到一個不是在當前模塊中定義的符號時,它會假設該符號是在某個模塊中定義的,生成一個連接器符號表條目而後交給連接器處理
    • 若是在連接器的任何模塊中都找不到這個被引用的符號,它就輸出一條錯誤信息而後終止
    • 對於多重定義的全局符號:打包

      函數和已經初始化的全局變量是強符號,未初始化的全局變量是弱符號
          規則:
                不容許有多個強符號
                若是有一個強符號和多個弱符號,那麼選擇強符號
                若是有多個弱符號,那麼從其中任選一個

7.7 重定位

  • 重定位由兩個步驟組成

    • 重定位節和符號定義:連接器將全部相同類型的節合併爲同一類型的新的聚合節
    • 重定位節中的符號引用:連接器修改代碼節和數據節中對每一個符號的引用,使得它們指向正確的運行時的地址

與靜態庫鏈接

  • 概述:編譯系統提供一種機制,將全部相關的目標模塊打包爲一個單獨的文件,稱爲靜態庫,它能夠用作連接器的輸入
  • 優勢:

    • 相關的函數能夠被編譯爲獨立的目標模塊,而後封裝成一個單獨的靜態庫文件
    • 連接器只拷貝被引用程序引用的目標模塊,這就減小了可執行文件在磁盤和存儲器中的大小

加載可執行文件

  1. 加載器將可執行目標文件中的代碼和數據從磁盤拷貝到存儲器中,而後經過跳轉到程序的第一條指令來運行程序
  2. 存儲器映像
  3. 每一個Unix程序都要加一個運行時存儲器映像

總結

這一章是上學期學過的連接,仍是比較熟悉的,可是由於某些緣由,書已經不在身邊了,因此借鑑的劉蔚然學霸的博客。雖然借鑑的有點多,但我至少複習透了。

相關文章
相關標籤/搜索