程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 讀懂IL代碼(三),讀懂il代碼

讀懂IL代碼(三),讀懂il代碼

編輯:C#入門知識

讀懂IL代碼(三),讀懂il代碼


由於要寫畢業論文的緣故,最近比較沒有時間寫,總是要抽出時間抽出時間。诶,這樣的生活比較煩躁。

這一篇主要寫委托、類、方法的IL代碼,一一來說明。

委托:搞過C#的都應該清楚,委托實際上是一個類。編譯器會把它編譯成一個類,繼承自MulticastDelegate的類,裡面有三個方法,BeginInvoke,EndInvoke和Invoke,當我們使用委托方法名進行調用方法時,編譯器內部實際上是調用了Invoke方法(語法糖)。

以下就用簡單的代碼來掩飾一下委托的IL代碼

先來看看編譯器把委托編譯成什麼樣子:

好啦,下面就是重要的IL代碼啦,其實大家可以先自己去嘗試解析一下,我覺得當自己去嘗試某些東西的話,會記得更牢一些。

看到上面的代碼,是否有的指令非常熟悉,我覺得大部分的指令我們在前面兩篇都有講過了,不過在這裡我還是一句一句的解釋

.method private hidebysig static void Main(string[] args)cilmanaged
{
    .entrypoint //入口啦,這個說過很多次了。
    .maxstack 2 //評估堆棧可能容納數據項的最大個數。
    .locals init (
        [0] class TestDemo4.Program/MyDele dele) //上面已經講過了,委托最終是編譯成類的,所以這裡是一個類類型的變量dele,存儲在調用棧。
    L_0000: nop //No Operation。
    L_0001: ldnull //將空引用推送到計算堆棧上。
    L_0002: ldftn void TestDemo4.Program/UserInfo::PrintName(string) //將指向實現特定方法的本機代碼的非托管指針(native int類型)推送到計算堆棧上,也就是指將方法指針壓入評估棧中。
    L_0008: newobj instance void TestDemo4.Program/MyDele::.ctor(object, native int)//創建委托實例並壓入評估棧中。這一步會調用委托的構造函數(.ctor),這個構造函數需要兩個參數,一個是對象引用,這裡就是L_0001:ldnull:空對象,第二個參數是方法的地址L_0002中的動作。
    L_000d: stloc.0 //將評估棧中的委托實例保存到調用棧的第0個位置上。
    L_000e: ldloc.0 //獲取調用棧中第0位置的值(委托實例),並壓入評估棧中。
    L_000f: ldstr "Helius" //加載字符串,在托管堆中創建Helius對象,並把引用存放在評估棧上。
    L_0014: callvirt instance void TestDemo4.Program/MyDele::Invoke(string) //Invoke,看到沒,委托實例調用了Invoke的的方法來執行。callvirt只能調用實例方法和虛方法,不能調用靜態方法
    L_0019: nop //No Operation
    L_001a: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //調用ReadKey方法。
    L_001f: pop //清空評估棧。
    L_0020: ret //return。
}

--------------------------------------------------------------------------------分割線------------------------------------------------------------------------------------------------

類與方法的常規代碼:

這裡先從Person類開始解析,這裡我使用到了自動屬性,大家應該也都很明了,編譯器把自動屬性編譯成了一個私有字段和兩個方法。

 OK啦,又到了看Main函數的IL代碼時間了

上面的IL代碼中,只有一個指令在之前沒有出現過,那就是newobj這個指令,這個指令的意思是創建一個實例對象,並將實例對象的引用推送到計算堆棧上,也就是評估棧上。

我不想一句一句的解析了,我現在就用畫圖的形式來解釋一下實例化一個類的過程:

其實我這裡也只是泛泛之談而已,我覺得大家完全有必要自己寫一個小Demo,編譯完之後使用Reflector看一下IL代碼,這樣子會更清晰一些。而且有不懂的地方,我覺得大家完全可以自行百度或者拿出來讓大家討論一下。

下一章再講一下流程控制的IL代碼後,我想應該就可以結束掉這部分內容了。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved