Re: [問題] 連結&載入器,分段分頁,Binding關係

看板LinuxDev作者 (夏克維夫)時間9年前 (2015/07/11 20:41), 編輯推噓0(003)
留言3則, 1人參與, 最新討論串2/3 (看更多)
※ 引述《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去讀 程式設計師的自我修養 那本書真的很珍貴 因為我竟然發現 這麼重要的技術 竟然很少原文書 上述回答可能有誤 請各位大大多多指教了<(_ _)> : 謝謝 --

aldnoah zero演完了,下一季是aldnoah stay night嗎
-- ※ 發信站: 批踢踢實業坊(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
文章代碼(AID): #1LeGxpy0 (LinuxDev)
討論串 (同標題文章)
文章代碼(AID): #1LeGxpy0 (LinuxDev)