Re: [問題] 連結&載入器,分段分頁,Binding關係
※ 引述《gigigigi (gigigigi)》之銘言:
: 何謂Binding
: Def: 決定程式執行的起始位址。
: 即:程式要在內存的哪個地方開始執行。
: 可能的Binding時期有三個:
: 1. Compiling Time
: 2. Loading Time
: 3. Execution Time
: 3-1 : Dynamic Binding
: 3-2 : Dynamic Loading
: 鏈接器( Linker )是把不同部分的代碼和數據,收集、組合成為一個可加載、可執行的文
: 件。
: 加載器( Loader )把可執行文件從外存裝入內存並進行執行
: MMU : 分段 + 分頁
: 分段 - 邏輯位址 -> 線性位址
: 分頁 - 線性位址 -> 實體位址
: _________________________________________________________________________________
: 我被上面情況給搞的有點亂 , 有下面幾點疑惑
: 1.
: Binging 三個時期程式位址都算是虛擬位址?
是的 除非你玩的是沒MMU的處理器
: Compiling Time 位址是由編譯器計算出來?
不算是 其實是由連結器那邊設定的
: Loading Time 是由 加載器 計算出位址?
: Execution Time : 位址是 Local Address + Base Register ?
小弟不才 可能不完全正確 但其實元PO問的事情沒那麼複雜
用一句話回答的話就是:把一切交給虛擬位址就對了!
基本上會考慮到實體位址的就只有一位:核心
包括編譯器連結器在內 都是用虛擬位址在思考
而我剛剛講的 編譯完的位址 其實是由叫做linker script的東西設定的
這些script是ld在編譯的鏈結時期讀取的
(script路徑可由 ld --verbose | grep SEARCH_DIR 得知)
決定的事情包括最重要也最基本的:執行檔的開頭要載到哪一個位址(虛擬位址)
也多虧了虛擬位址 每一個執行檔 檔案裡寫的開始執行位址都可以一樣
反正實際在記憶體中的位址是由核心分配的嘛
linker script其實常常用在一些很hack的地方
例如linux kernel 會把某些符號在鏈結時期改成另外一個名字
Mozilla B2G (Firfox OS)也利用linker script
把一些重要的libc符號 映射到他們自己實作的版本 說可以避免concurrency(?
: 2.
: 目前Linux 是用MMU 段式 + 頁式 ?
這個問題蠻好玩的 因為x86大力鼓吹段式(segment) 但Linux為了跨平台著想
因為很多RISC家族根本沒有segment的概念 所以是採用頁式(page)
: Linux 跟 Binding三個時期有關係嘛?
: Binding三個時期技術是早期的技術嘛? 目前有機會使用到嘛?
其實我不太知道你這邊的Binding是什麼意思
因為小弟是搞編譯器的 第一個就想到Name Binding XDD
: 3.
: 鏈接器( Linker )是把不同部分的代碼和數據,收集、組合成為一個可加載、可執行的文
: 件。
: 我認知編譯出執行文件使用 objdump -d 就可以看到虛擬位址 , 就位址是ld Linker
: 計算出來的嘛? 如果是它是屬於哪個Binding?
: gcc -g test.c
: 使用 objdump -d ./a.out
: 08048414 <main>:
: 8048414: 55 push %ebp
: 8048415: 89 e5 mov %esp,%ebp
: 8048417: 6a 03 push $0x3
: 8048419: 6a 02 push $0x2
: 804841b: e8 e1 ff ff ff call 8048401 <foo>
: 8048420: 83 c4 08 add $0x8,%esp
: 8048423: b8 00 00 00 00 mov $0x0,%eax
: 8048428: c9 leave
: 8048429: c3 ret
: 804842a: 66 90 xchg %ax,%ax
: 804842c: 66 90 xchg %ax,%ax
: 804842e: 66 90 xchg %ax,%ax
: 加載器( Loader )把可執行文件從外存裝入內存並進行執行 <-- 這過程有經過虛擬位址
: 映射實體位址轉換嘛?
虛擬位址的映射(到實體位址)完全是執行的時候做的事喔
: Linux 系統的加載器( Loader ) 這是位於 linux kernel 裡面?
是的 加載執行檔一定是作業系統的事
ld.so的角色呢(不是編譯時期的ld)?他是負責解析動態函式庫(.so)的相關事情
例如幫忙resolve現在執行需要的so並加以載入
那那個so載入的位址呢?前面講過 每個執行檔編譯出來 開始的虛擬位址可以一樣
但so的虛擬位址並不是寫死的
其中的技術就是PIC(Position independent code) 也就是編譯so時下的 -fPIC
就如字面上講的 他並不是絕對位址 而是相對位址
因此ld.so就可以把他載到執行位址空間的任何一個地方
詳細的技術比較複雜一點 這邊寫不下 推薦原PO去讀 程式設計師的自我修養
那本書真的很珍貴 因為我竟然發現 這麼重要的技術 竟然很少原文書
上述回答可能有誤 請各位大大多多指教了<(_ _)>
: 謝謝
--
推
,
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.155.231
※ 文章網址: https://www.ptt.cc/bbs/LinuxDev/M.1436618483.A.F00.html
→
07/11 21:13, , 1F
07/11 21:13, 1F
→
07/11 21:14, , 2F
07/11 21:14, 2F
→
07/11 21:14, , 3F
07/11 21:14, 3F
討論串 (同標題文章)
LinuxDev 近期熱門文章
PTT數位生活區 即時熱門文章