你的C#代碼是怎么跑起來的(一)


寫了那么多C#代碼,大家有沒有想過自己寫的代碼編譯后的可執行文件內部是什么樣子,是怎樣在系統上運行的?

編譯成exe,然后雙擊exe文件運行,這中間到底發生了些什么呢,這篇先來剖析下exe內部的樣子:

我們知道C#代碼編譯后的結果是IL(Intermediate Language),那生成的exe文件里面都是IL嗎,當然不會。

C#生成的exe既然是window下可執行文件,那也就是標准的PE文件,和普通win32的exe文件格式一樣。我們來看下exe文件的格式:

dll文件本質上和exe一樣,只是少了入口函數。

MS-DOC MZ Header和MS-DOS Stub是為了兼容DOS系統存在的,目的是使這個exe在DOS下執行時彈出一個提示"This program cannot be run in DOS mode"。

PE Header包含了這個文件的一些信息,如:文件創建日期,文件類型,Section的數量,Optional Header的大小等等。詳細可以參考Winnt.h里的結構_IMAGE_FILE_HEADER。

PE Optional Header則包含了文件的版本號以及重要的基地址和AddressOfEntryPoint(RVA-Relative Virtual Address),這是程序執行的入口地址,雙擊exe后就從這里開始執行。對C#程序來說,這里指向的是.net的核心庫MsCorEE.dll的_CorExeMain()函數。當然這是針對XP系統的,XP以后的系統,OS Loader已經可以判斷出這個PE是否包含CLR頭來決定是否運行MsCorEE.dll的_CorExeMain()函數。

Section有很多,包括代碼節,數據節等,C#程序會把CLR頭,元數據,IL放在這里面。

CLR是什么呢,全稱Common Language Runtime,公共語言運行時,CLR主要是管理程序集,托管堆內存,異常處理和線程同步等等。

CLR頭具體可以參考CorHdr.h中的IMAGE_COR20_HEADER結構,如下:

 1 typedef struct IMAGE_COR20_HEADER
 2     {
 3         // CLR版本信息
 4         ULONG cb;
 5         USHORT MajorRuntimeVersion;
 6         USHORT MinorRuntimeVersion;
 7 
 8         IMAGE_DATA_DIRECTORY MetaData; //元數據
 9         ULONG Flags;
10         ULONG EntryPointToken;  //入口函數Main的標識
11 
12 
13         IMAGE_DATA_DIRECTORY Resources;  //資源
14         IMAGE_DATA_DIRECTORY StrongNameSignature;  //強名稱標識
15 
16 
17         // Regular fixup and binding information
18         IMAGE_DATA_DIRECTORY CodeManagerTable;
19         IMAGE_DATA_DIRECTORY VTableFixups;
20         IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
21 
22         // Precompiled image info (internal use only - set to zero)
23         IMAGE_DATA_DIRECTORY ManagedNativeHeader;
24 
25     }
26     IMAGE_COR20_HEADER;

元數據很重要,驗證代碼類型安全,GC的對象引用跟蹤還有我們常用的反射都需要用到元數據。

元數據主要由定義表,引用表,清單表組成。

定義表包括應用所有的類型,方法,字段,屬性,參數,事件的定義,代碼里任何的定義項都可以在這個表里找到,反射就是靠這個表只要一個名字就能得到屬性或函數。運行時的類型安全檢查也離不開它。

引用表包括程序集,類型和成員的引用,我們知道GC在回收內存時先默認認為所有對象都是垃圾,然后通過線程棧上的根(cpu寄存器,局部變量,參數,靜態變量)找引用的對象,能找到的說明還在使用就去掉垃圾標記,這個表可以讓GC在回收內存時方便從根找到所有引用。

清單表主要是程序集,文件,資源的定義。

IL就不多說了,不了解的朋友可以參考小弟的另一篇文章:30分鍾?不需要,輕松讀懂IL

元數據和IL都可以通過工具ildasm.exe來查看。

以上就是C#生成的exe文件的主要結構,下篇再講exe文件的運行過程,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM