天天看點

CLR寄宿(中) 托管exe檔案的加載和執行CLR寄宿(中)  托管exe檔案的加載和執行

托管exe檔案的加載和執行過程在之前的文章做過簡要的介紹,現在結合本章的内容進行詳細的分析。

托管exe檔案被啟動的時候,首先被PE Loader載入。PE Loader載入exe檔案之後,會分析PE檔案頭的data directory table,如果CLR_Header内的值不為0,表示該檔案是托管PE檔案,PE Loader 會立即載入MsCorEE.dll,并且執行 MsCorEE.dll内的_CorExeMain()函數。

如果是Windows XP以前版本的作業系統(比如Windows 2000),當Windows 2000 的 Loader 将exe檔案載入之後,會檢查PE Header 的 data directory table,将Import Table 所記錄的資料都載入記憶體,就是MsCorEE.dll。接着找出 PE header 内程式的入口點,并執行此處的代碼。這是 x86 機器碼,由編譯器自動産生,隻有一道指令 (6 bytes),為“FF 25 00 20 40 00”,翻譯成 x86彙編語言就是“JMP DWORD PTR [402000]”,其中 0x00400000 是 exe檔案的 image base,而 0x2000 是 import address table 的 RVA (此處是_CorExeMain() 的偏移位址),是以執行“JMP DWORD PTR [402000]”的結果會跳到 MsCorEE.dll 的_CorExeMain()。

在執行_CorExeMain()之後,其中的代碼首先判斷需要載入的CLR版本。

CLR啟動之後,接下來要做的就是初始化工作,為托管程式建立程序,申請記憶體空間,建立線程池和應用程式域。第一個建立的應用程式域被稱為Default AppDomain。

初始化之後,要載入MsCorLib.dll元件和其中的子產品。

子產品載入之後,會調用class loader 來載入 MsCorLib 内相關的 class。載入的 class 順序依次為:

1)        System.Object

2)        System.ICloneable

3)        System.Collections.IEnumerable

4)        ……

5)        System.AppDomain

6)        System.LoaderOptimization

7)        System.Runtime.Remoting.Proxies.__TransparentProxy

注意 此時并未載入 MsCorLib 内全部的 class,隻載入目前需要的 class。

載入class之後,CLR會生成主線程,生成主線程又需要載入以下的類:

System.Threading.Monitor

System.IAppDomainSetup

System.AppDomainSetup

System.Char

System.Runtime.InteropServices.RuntimeEnvironment

System.RuntimeFieldHandle

System.Runtime.CompilerServices.RuntimeHelpers

System.Environment

主線程生成之後就是載入應用程式的元件到應用程式域,之後才真正進入應用程式的主函數。

進入Main()函數之後,會調用JIT編譯器将IL代碼編譯成本地代碼執行。 

本文轉自懸魂部落格園部落格,原文連結:http://www.cnblogs.com/xuanhun/archive/2012/06/23/2559351.html,如需轉載請自行聯系原作者