類zzz從System.Object中派生。在.Net中,為了定義類型的 一致性,所有的類型最終都派生於System.Object。因此,所有的對象都有一個共同的基類Object。在IL 中,類從其它類中派生,與C++、C#和Java的表現方式相同,
a.il
.module aa.exe
.subsystem 3
.corflags 1
.assembly extern mscorlib
{
.originator = (03 68 91 16 D3 A4 AE 33 )
.hash = (52 44 F8 C9 55 1F 54 3F 97 D7 AB AD E2 DF 1D E0
F2 9D 4F BC )
.ver 1:0:2204:21
}
.assembly a as "a"
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.class private auto ansi zzz extends System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ldstr "hell"
call void System.Console::WriteLine(class System.String)
ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() il managed
{
.maxstack 8
ldstr "hell1"
call void System.Console::WriteLine(class System.String)
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
}
Output
hell
你一定想知道為什麼我們會編寫出這麼難看的程序。在迷霧 驅散之前你需要保持耐心,所有的一切就要開始有意義了。我們將逐個解釋新引進的函數和特性。
.ctor: 我們引進了一個新的函數.ctor,它調用了WriteLine函數來顯示hell1,但是它沒有被調 用。.ctor涉及到了構造函數。
rtspecialname: 這個特性會告訴運行時——函數的名 稱是特殊的,它會以一種特殊的方式被對待。
specialname: 這個特性會提示編譯器和工具 ——函數是特殊的。運行時可能選擇忽略這個特性。
instance: 一個常規的函數會被 一個實例函數調用。這樣一個函數與一個對象關聯,不同於靜態方法,後者關聯到一個類。
在合 適的時候,為函數選擇特定名稱的原因會變得明朗。
ldarg.0: 這是一個匯編器指令,它加載this 指針或第0個參數的地址到執行棧上。我們隨後將詳細解釋ldarg.0。
mscorlib: 在上面的程序中 ,函數.ctor會被基類System.Object調用。通常,函數的名稱以包括代碼的庫的名稱作為前綴。這個庫的 名稱被放置在方括號中。在這個例子中,它是可選的——因為mscorlib.dll是默認的庫,並且 它包括了.Net所需要的大部分類。
.maxstack: 這個偽指令指定了在一個方法被調用時,能夠出現 在計算棧上的元素的最大數量。
.module: 所有的IL文件必須是一個邏輯實體的一部分,或它們的 組合體,我們將這些實體稱為模塊(module)。文件被添加到使用了.module偽指令的模塊中。模塊的名 稱可能被規定為aa.exe,但是可執行文件的名稱和前面保持一樣,即a.exe。