托管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/
查看本欄目