[你必須知道的.NET] 第十三回:從Hello, world開始認識IL
[2] [你必須知道的.NET] 第十三回:從Hello, world開始認識IL
系列文章導航:
[你必須知道的.NET] 第四回:后來居上:class和struct
[你必須知道的.NET] 第五回:深入淺出關鍵字---把new說透
[你必須知道的.NET] 第六回:深入淺出關鍵字---base和this
[你必須知道的.NET] 第七回:品味類型---從通用類型系統開始
[你必須知道的.NET] 第八回:品味類型---值類型與引用類型(上)-內存有理
[你必須知道的.NET] 第九回:品味類型---值類型與引用類型(中)-規則無邊
[你必須知道的.NET] 第十回:品味類型---值類型與引用類型(下)-應用征途
[你必須知道的.NET] 第十一回:參數之惑---傳遞的藝術(上)
[你必須知道的.NET] 第十二回:參數之惑---傳遞的藝術(下)
[你必須知道的.NET] 第十三回:從Hello, world開始認識IL
[你必須知道的.NET] 第十四回:認識IL代碼---從開始到現在
[你必須知道的.NET] 第十六回:深入淺出關鍵字---using全接觸
[你必須知道的.NET]第二十二回:字符串駐留(上)---帶著問題思考
[你必須知道的.NET]第三十二回,深入.NET 4.0之,Tuple一二
本文將介紹以下內容:
• IL代碼分析方法
• Hello, world歷史
• .NET學習方法論
1. 引言
1988年Brian W. Kernighan和Dennis M. Ritchie合著了軟件史上的經典巨著《The C programming Language》,我推薦所有的程序人都有機會重溫這本歷史上的經典之作。從那時起,Hello, world示例就作為了幾乎所有實踐型程序設計書籍的開篇代碼,一直延續至今,除了表達對巨人與歷史的尊重,本文也以Hello, world示例作為我們扣開IL語言的起點,開始我們循序漸進的IL認識之旅。
2. 從Hello, world開始
首先,當然是展示我們的Hello, world代碼,開始一段有益的分享。
Code
這段代碼執行了最簡單的過程,向陌生的世界打了一個招呼,那么運行在高級語言背后真相又是什么呢,下面開始我們基于上述示例的IL代碼分析。
3. IL體驗中心
對編譯后的可執行文件HelloWorld.exe應用ILDasm.exe反編譯工具,還原HelloWorld的為文本MSIL編碼,至于其工作原理我們期望在系列的后續文章中做以交代,我們查看其截圖為:
由上圖可知,編譯后的IL結構中,包含了MANIFEST和HelloWorld類,其中MANIFEST是個附加信息列表,主要包含了程序集的一些屬性,例如程序集名稱、版本號、哈希算法、程序集模塊等,以及對外部引用程序集的引用項;而HelloWorld類則是我們下面介紹的主角。
3.1 MANIFEST清單分析
打開MANIFEST清單,我們可以看到
從這段IL代碼中,我們的分析如下:
• .assembly指令用于定義編譯目標或者加載外部庫。在IL清單中可見,.assembly extern mscorlib表示外部加載了外部核心庫mscorlib,而.assembly HelloWorld則表示了定義的編譯目標。值得注意的是,.assembly將只顯示程序中實際應用到的程序集列表,而對于加入using引用的程序集,如果并未在程序中引用,則編譯器會忽略多加載的程序集,例如System.Data將被忽略,這樣就有效避免了過度加載引起的代碼膨脹。
• 我們知道mscorlib.dll程序集定義managed code依賴的核心數據類型,屬于必須加載項。 例如接下來要分析的.ctor指令表示構造函數,從代碼中我們知道沒有為HelloWord類提供任何顯示的構造函數,因此可以肯定其繼承自基類System.Object,而這個System.Object就包含在mscorlib程序集中。
• 在外部指令中還會指明了引用版本(.ver);應用程序實際公鑰標記(.publickeytoken),公鑰Token是SHA1哈希碼的低8位字節的反序(如下圖所示),用于唯一的確定程序集;還包括其他信息如語言文化等。
• HelloWorld程序集中包括了.hash algorithm指令,表示實現安全性所使用的哈希算法,系統缺省為0x00008004,表明為SHA1算法;.ver則表示了HelloWorld程序集的版本號;
• 程序集由模塊組成, .module為程序集指令,表明定義的模塊的元數據,以指定當前模塊。
• 其他的指令還有:imagebase為影像基地址;.file alignment為文件對齊數值;.subsystem為連接系統類型,0x0003表示從控制臺運行;.corflags為設置運行庫頭文件標志,默認為1;這些指令不是我們研究的重點,詳細的信息請參考MSDN相關信息。