在exe文件上執行ildasm後,我們觀察一 下該程序所生成的IL代碼。先排除一部分代碼——它們對我們理解IL是沒有任何幫助的 ——包括一些注釋、偽指令和函數。剩下的IL代碼,則和原始的代碼盡可能的保持一樣。
Edited a.il
.assembly mukhi {}
.class private auto ansi zzz extends System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ldstr "hi"
call void System.Console::WriteLine(class System.String)
call void zzz::abc()
ret
}
.method public hidebysig static void abc() il managed
{
ldstr "bye"
call void System.Console::WriteLine(class System.String)
ret
}
}
c:\il>ilasm a.il
Output
hi
bye
通過研究IL代碼本身來掌握IL這門技術的好處是,我們從C#編譯 器那裡學習到如何編寫相當好的IL代碼。找不到比C#編譯器更權威的“大師”來教導我們關於 IL的知識。
創建靜態函數abc的規則,與創建其它函數是相同的,諸如Main或vijay。因為abc是一 個靜態函數,所以我們必須在.method偽指令中使用修飾符static。
當我們想調用一個函數時,必 須依次提供以下信息:
返回的數據類型
類的名稱
被調用的函數名稱
參數的 數據類型
同樣的規則還適用於當我們調用基類的.ctor函數的時候。在函數名稱的前面寫出類的名 稱是必須的。在IL中,不能做出類的名稱事先已經建立的假設。類的默認名稱是我們在調用函數時所在的 類。
因此,上面的程序首先使用WriteLine函數來顯示hi,並隨後調用靜態函數abc。這個函數還 使用了WriteLine函數來顯示bye。
a.cs
class zzz
{
public static void Main()
{
System.Console.WriteLine("hi");
}
static zzz()
{
System.Console.WriteLine("bye");
}
}
a.il
.assembly mukhi {}
.class private auto ansi zzz extends System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ldstr "hi"
call void System.Console::WriteLine(class System.String)
ret
}
.method private hidebysig specialname rtspecialname static void .cctor() il managed
{
ldstr "bye"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
}
Output
bye
hi