天天看點

由淺入深CIL系列:1.初步認識CIL通用中間語言

    CIL簡介:CIL(Common Intermediate Language)中文名為通用中間語言,注意它曾經被稱為微軟中間語言或MSIL,它是一種類似于JAVA位元組碼的語言。在微軟語言平台中,不管程式員 使用C#、VB.NET或者J#等語言編寫的程式進行編譯的時候,編譯器将這幾種語言編寫的源代碼編譯為CIL(微軟中間語言)語言,此時再通過 JIL(Just In Time實時編譯器)編譯為針對各種不同CPU的指令(注意因為是實時的編譯器,是以它運作的時候是隻運作需要編譯的CIL語言段,而不是全部一下編譯 完,這是為了提高效率。)

        了解CIL好處:1.本系列文章用于研究和探讨CIL中間語言,在實際應用中能夠讓你選擇更好的文法,例如:是選擇For還是選擇Foreach做循環周遊?

                       2.深入的了解.NET記憶體的配置設定以及底層的語言運作原理。例如:.Net值類型和引用類型的記憶體配置設定?

                       3.使用System.Reflection.Emit下的Emit加載CIL指令,動态建立類。

        初步認識CIL:

        一、我們建立一個C#語言編寫的控制台程式命名為ConsoleApplication6,然後鍵入以下代碼:

namespace ConsoleApplication6 

class Program 

static void Main(string[] args) 

string a = "Hello World!"; 

Console.WriteLine(a); 

        二、很明顯上面的語句将會在控制台輸出一個字元串“Hello World!”,那麼這個控制台程式的CIL語言是怎樣的呢?我們下面可以通過VS2010自帶的SDK工具IL Disassembler(ILDASM)打開上面應用程式建立的ConsoleApplication6.exe檔案,以檢視其CIL語言。如下圖方式 以打開ILDASM工具:

<a target="_blank" href="http://blog.51cto.com/attachment/201204/093802414.jpg"></a>

        打開ILDASM工具界面如下:

<a target="_blank" href="http://blog.51cto.com/attachment/201204/093802719.jpg"></a>

        本圖代表一個ConsoleApplication6的命名空間下有一個類叫ConsoleApplication6.Program,這個類下面有一個 類清單(.class private auto ansi beforefieldinit)+預設構造函數(.ctor:void())+靜态函數(Main:void(string[]))。

        注意:上圖的界面中有一些紅色的三角形,或者藍色的盾形等分别代表更多資訊或者是命名空間等資訊,其具體含義如下圖所示:

        三、點選預設構造函數.ctor:void()我們可以看到這個構造函數的CIL語言如下: 

.method public hidebysig specialname rtspecialname 

//.method表示對方法 

instance void .ctor() cil managed 

// 代碼大小 7 (0x7) 

.maxstack 8 

IL_0000: ldarg.0 

IL_0001: call instance void [mscorlib]System.Object::.ctor() 

IL_0006: ret 

} // end of method Program::.ctor 

 ldarg.0 将索引為 0 的參數加載到計算堆棧上

           call 調用由傳遞的方法說明符訓示的方法

           ret 從目前方法傳回,并将傳回值(如果存在)從調用方的計算堆棧推送到被調用方的計算堆棧上

           意義:将索引為0的參數加載到堆棧上,然後調用System.Object對象的構造函數執行個體化對象,然後傳回。          

        四、點選靜态函數Main:void(string[]),可以打開一個界面,界面内看到CIL語言如下:

.method private hidebysig static void Main(string[] args) cil managed 

.entrypoint //程式進入點 

// 代碼大小 15 (0xf) 

.maxstack 1 //堆棧配置設定 

.locals init ([0] string a) 

IL_0000: nop 

IL_0001: ldstr "Hello World!"//壓入字元串,堆棧壓操作 

IL_0006: stloc.0 //從計算堆棧的頂部彈出目前值并将其存儲到索引 0 處的局部變量清單中。 

IL_0007: ldloc.0 //将索引 0 處的局部變量加載到計算堆棧上。 

IL_0008: call void [mscorlib]System.Console::WriteLine(string) 

//呼叫WriteLine函數列印Hello World 

IL_000d: nop 

IL_000e: ret //傳回 

} // end of method Program::Main 

        通過本文章,我們初步的認識了CIL中間語言。也認識了一些CIL的指令代碼

本文轉自程興亮 51CTO部落格,原文連結:http://blog.51cto.com/chengxingliang/826584