全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2437
推到 Plurk!
推到 Facebook!

Rebase your modules (1)

 
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-09-06 21:25:03 IP:61.219.xxx.xxx 未訂閱
你的 User double click 了一個 icon, 或是在程式集裡點選了一個icon, 正要啟動你的程式, 而你有對你的程式出貨版本作好啟動時期的最佳化嗎?    在今天, 記憶體跟硬碟便宜的跟不要錢似的. 在我第一次看到 Windows 1.0 的時候, 據說, 當時的 RAM 與等重的黃金等價.    因此, Windows 的主要設計目標之一, 就是盡可能的共享資源, 以節省記憶體. (雖然它實在大到讓你感受不到有這麼一個目標存在... XD)    基於這個原則, 當你的程式被 CreateProcess() 喚起時, Loader 會作以下的動作: 1. 搜索這個執行檔, 如果找不到就傳回False 2. 建立新的 Process 和行程所屬的記憶體空間 3. 在記憶空間中保留一個足夠的空間給該執行檔, 然後將該執行檔的 Image mapping 到該記憶空間. 換句話說, Win32 將 PE32 Module 當成是一個 Extension Paging. 4. 系統會去讀取 .idata section (Import Data section), .idata會列出這個執行檔隱式連結(靜態連結)的 DLL 和函式, Loader會接著呼叫 LoadLibrary() 把這些 DLL 載入. 載入方法跟 Exe 檔其實是一樣的 (參考 3.)    而每一個 PE Module 都有一個預設的 Base Address, 當 Loader 在將 PE Module Image mapping 到記憶空間的時候, 會優先選用 Module header 中所記載的 Base Address. 如果該 Address 無人使用, 且連續空間也夠大, Loader 就會直接將該 PE Module mapping 到那個位置去 (Header所記載的Base Address).    如果很不幸的, 那個位置被人佔用了, 或是那個位置雖然沒有人用, 可是連續空間不夠大, 放不下這個 PE Module, 那麼, 系統將被迫動用第二規則: Relocation. Loader會先去看該 PE Module 是否有 .reloc section. 如果這個 PE Module 沒有 .reloc Section, 表示該 PE Module 無法被 relocation, 於是, Loader 將放棄載入, 傳回錯誤. 如果找到了 .reloc Section, Loader會開始找尋一個無人使用, 且連續空間夠大的位置, 並把那個 Address 當成新的 Base Adddress, 並把該 PE Module 中所有需要重新 relocation 的位置重新定址.     Relocation 作什麼事呢, Relocation 把 PE Module 中的所有 reference address 都重新定位. 好吧, 聽起來很抽像, 舉個例子好了:    
int A; // in global scope    void TestFunc(void)
{
    A = 1;
}
假設目前的預設 Base Address - 0x400000, 這一段 Code, TestFunc() 可能被翻譯成像下面那樣:
    push    ebp
    mov     ebp, esp
    mov     [0x0040363C], 0x00000001        ; A = 1
    pop     ebp
    ret
上面紅色那一行注意到了嗎? 如果 default base address 不能用, 而新定位的 Base Address = 0x500000, 它就會被改這樣:
    push    ebp
    mov     ebp, esp
    mov     [0x0050363C], 0x00000001        ; A = 1
    pop     ebp
    ret
因此, 這段 Code, A 的 RVA (相對虛擬位置) = 0x0000363C. 當 Base Address 被重定為 0x500000, New Address = New base address + RVA = 0x500000 + 0x0000363C = 0x0050363C. 然而 Win32 系統為了節省記憶體的開銷, 所以設有 Copy-On-Write 的機制. 所謂的 Copy-On-Write 機制, 指的是: 當某一個 Page (x86為4K, Alpha/IA64為8K) 如果有被寫入的需要, 則 OS 會將該 Page 複製一份, 並將發出寫入請求的 Process 的 page mapping table 改掉, 指向新 copy 出來的 page. 如此, 可以作到資源最大共享. 根據 Win32 Copy-on-write 的機制, 所有要被 Relocaton 的程式碼, 都會被以 Page 為單位重新複製一份, 在 WinNT 中, 該 Page 會被建立在 Swap File 中, 而 Win9x/Me 中, 該 Page 會被建立在記憶體中. 由於需要重新定位 (Relocation), load 需要時間去分析 .reloc section, 這會使得 Module 載入速度變長, 影響到你的程式, 使得啟動和始時間變長. 另外, 這樣你需要付出額外的記憶體成本. 記得之前說過的嗎? Win32 系統會把 PE Module 當成 extension swap. 當在記憶體中執行的程式有必要被 swap-out 出去的時候, 程式碼的部分會直接被丟棄掉, 而當它需要再被載回去執行的時候, 如果你的 PE Module 沒有被 relocation, 就可以直接從 PE Module 中再次載入. 如果你的 PE Module 有被 Relocation 過, 系統必需從 Swap File 中載入, 這將使得可以被使用的 Swpa File 空間變少. 換句話說, 總記憶體變得更少了. 然而, Relocation 的戲碼天天在上演著. Microsoft Visual C++ 可以在 Project Settings 的 Link tabs 設定 Base Address, 如果你不填 (如下圖保持空白), 則 Microsoft Visual C++ 對於 .Exe 檔的 Base Address 預設值是 0x400000, DLL 是 0x10000000. 下面是 Dump 出來的資訊:
[C:\projects\AoiDBG\Output]tdump disasm2.dll    Turbo Dump  Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
                   Display of File DISASM2.DLL    ...    Image base               10000000    ...    [C:\projects\OLG\Output]tdump LoginServer.exe    Turbo Dump  Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
                     Display of File LOGINSERVER.EXE    ...
Image base               00400000
...
而 Borland C++ Builder 6, Exe 和 DLL 都是定址在 0x400000. 以下是 Dump 出來的資訊:
[C:\projects\OLG\Output]tdump security.dll    Turbo Dump  Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
                     Display of File SECURITY.DLL    ...
Image base               00400000
...    [C:\projects\AoiDBG\Output]tdump gui_aoidebug.exe    Turbo Dump  Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
                   Display of File GUI_AOIDEBUG.EXE    ...    Image base               00400000    ...    
而我也相信, 很多人都是直接套用 Default setting. 待續 --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子 發表人 - miyu 於 2003/09/06 21:34:25 後續文章:http://delphi.ktop.com.tw/topic.php?TOPIC_ID=37030
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-09-06 23:51:40 IP:61.224.xxx.xxx 未訂閱
期待您的續作...    PS1. 是否有說明這類系統運作的書可以推薦呢?    PS2. 可否也解釋一下 Max/Min stack/heap size 的作用? 我曾經將 stack/heap 的 Max/Min 值都調大,結果也可以執行,但是會發生無法在 IDE 內除錯的情況,現在只好乖乖使用預設值  <>沒空更新的網頁... href="http://dllee.adsldns.org">http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-09-07 01:03:29 IP:61.219.xxx.xxx 未訂閱
引言: 期待您的續作...
Rebase寫完, 下一個會寫 Memory mapping file :p
引言: PS1. 是否有說明這類系統運作的書可以推薦呢?
就那幾本吧: Inside Microsoft Windows 2000 Undocument Windows 2000 Secrets: A Programmer's cookbook Programming Application for Microsoft Windows Debugging Applications 剩下的就是自己拿sice去挖了...:X
引言: PS2. 可否也解釋一下 Max/Min stack/heap size 的作用? 我曾經將 stack/heap 的 Max/Min 值都調大,結果也可以執行,但是會發生無法在 IDE 內除錯的情況,現在只好乖乖使用預設值 < face="Verdana, Arial, Helvetica"> 用tdump去看: Stack reserve/commit 00100000/00002000 (Max Stack Size: 0x00100000 / Min Stack Sizie: 0x00002000) Heap reserve/commit 00100000/00001000 (Max Heap Size: 0x00100000 / Min Heap size: 0x00001000) (紅色的是 BCB Options 裡的設定) 你在這邊看到兩個名詞. Borland 在 BCB 裡叫 Min Stack/Heap Size. 不過 TDump 跟 M$ 官方叫 Stack/Heap Commit size. BCB 裡叫 Max Stack/Heap Size Tdump / M$ Tools 稱作 Stack/Heap Reserve size. 我是覺得叫 Reserve/Commit 比較好. 一看就懂了.. Commit/Min Size 指的是一開始 Init 起來的時候, 會實際對應到實際記憶體的量. Reserve/Max 指的則是那最大能用到的量. Stack 是 Main process (main thread) stack. 至於那個 heap 則是指 default heap. default heap 一般都不會被 user 用到. 大都是被 API 用掉的. 或是, 在 Win16 裡, LocalAlloc() / GlobalAlloc() 也會用default heap 去配置記憶體. (不過win32裡, 這些東西都是為了相容才活著, 動作已經跟以前不一樣了) 至於為什麼會當掉 debugger ..我真的不知道耶 :X 去borland news問看看? --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子 --藍青第23回 發表人 - miyu 於 2003/09/07 01:18:55
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-09-07 13:51:36 IP:203.204.xxx.xxx 未訂閱
感謝分享  因發現您的 >沒空更新的網頁... href="http://dllee.adsldns.org">http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell.... 發表人 - dllee 於 2003/09/07 14:43:51
------
http://www.ViewMove.com
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-09-07 14:23:02 IP:61.219.xxx.xxx 未訂閱
引言: 因為是多人開發的 CASE,使得別人不能除錯,真是麻煩,最後,我取消設定改回原值,就又 OK 可以中斷除錯了。只是... 我也沒去算過我到底會用掉多少 stack... 會不會有任何意外發生呢?
有問題 OS 會叫的. 畢竟不管怎麼說, Stack 會被mapping到哪一個address去, 只有天知道.. 因此, OS 是有採行一些保護措施的. (參見 1.5 - comment)
引言: 對於 heap ... 說真的,我就更不解了,以最大值 0x00100000 才 1MB ,可是以之前所寫過的記憶體釋放程式,可以用全部的記憶體,甚至我也試過一次要求近 1GB 的記憶體也都可以過... 那這個最大值的設定有何用意?
那是 'Default heap', 上面有寫到, 是給 API 用的. 比方說 Unicode / MBCS 字串轉換就會用到. --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
系統時間:2024-05-03 19:02:42
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!