乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      淺析.NET MSIL代碼

       weijianian 2016-08-07


      來源:Joye.Net

      鏈接:http://www.cnblogs.com/yinrq/p/5486103.html


      一、前言


      IL是什么?


       Intermediate Language (IL)微軟中間語言


      C#代碼編譯過程?


      C#源代碼通過LC轉(zhuǎn)為IL代碼,IL主要包含一些元數(shù)據(jù)和中間語言指令;


      JIT編譯器把IL代碼轉(zhuǎn)為機器識別的機器代碼。如下圖



      語言編譯器:無論是VB code還是C# code都會被Language Compiler轉(zhuǎn)換為MSIL


      MSIL的作用:MSIL包含一些元數(shù)據(jù)和中間語言指令


      JIT編譯器的作用:根據(jù)系統(tǒng)環(huán)境將MSIL中間語言指令轉(zhuǎn)換為機器碼


      為什么ASP.NET網(wǎng)站第一次運行時會較慢,而后面的執(zhí)行速度則會相對快很多?


      當(dāng)你第一次運行.NET開發(fā)的站點時,CLR會將MSIL通過JIT進行編譯,最終轉(zhuǎn)換為執(zhí)行速度非??斓腘ative Code。這可以解釋。


      為什么要了解IL代碼?


      如果想學(xué)好.NET,IL是必須的基礎(chǔ),IL代碼是.NET運行的基礎(chǔ),當(dāng)我們對運行結(jié)果有異議的時候,可以通過IL代碼透過表面看本質(zhì);


      IL也是更好理解、認識CLR的基礎(chǔ);


      大量的實例分析是以IL為基礎(chǔ)的,所以了解IL,是讀懂他人代碼的必備基礎(chǔ),同時自己也可以獲得潛移默化的提高;


      二、如何把ILDasm導(dǎo)入到VS中


      想要看IL代碼需要使用ILDasm工具,工具一般在電腦的


      C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe


      也可以下載ILSpy:http:///


      把ILDasm導(dǎo)入到VS工具中,使用方便,具體如下:工具 - > 外部工具 


        


      導(dǎo)入之后,vs工具里面就有ILDasm工具了。以后想看IL代碼方便多了。


      IL代碼通過ILDasm反編譯后(左圖),ILDasm圖標(biāo)意義(右圖)


        



      三、分析IL代碼


      在分析IL代碼之前,要先理解幾個概念:



      圖片來源:https://msdn.microsoft.com/zh-tw/library/dd229210.aspx

      Managed Heap(托管堆):這就是NET中的托管堆,用來存放引用類型,它是由GC(垃圾回收器自動進行回收)管理;


      Call Stack(調(diào)用堆棧):調(diào)用堆棧:調(diào)用堆棧是一個方法列表,按調(diào)用順序保存所有在運行期被調(diào)用的方法。


      Evaluation Stack(計算堆棧):每個線程都有自己的線程棧,IL 里面的任何計算,都發(fā)生在 Evaluation Stack 上,其實就是一個 Stack 結(jié)構(gòu)??梢?Push,也可以 Pop。


      可以對照IL指令:指令列表,一步一步來分析IL代碼


      1、用C#寫一個簡單控制臺應(yīng)用程序


      using System;


      namespace ILDemo

      {

          class Program

          {

              static void Main(string[] args)

              {

                  int i = 1;

                  int j = 2;

                  int k = 3;

                  int answer = i + j + k;

                  Console.WriteLine('i+j+k=' + answer);

                  Console.ReadKey();

              }

          }

      }


      2、 用ILDasm打開bin下的.exe文件查看代碼,具體IL代碼如下:


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

      {

        .entrypoint 

        // 代碼大小       42 (0x2a)

        .maxstack  2

        .locals init ([0] int32 i,

                 [1] int32 j,

                 [2] int32 k,

                 [3] int32 answer)

        IL_0000:  nop

        IL_0001:  ldc.i4.1

        IL_0002:  stloc.0

        IL_0003:  ldc.i4.2

        IL_0004:  stloc.1

        IL_0005:  ldc.i4.3

        IL_0006:  stloc.2

        IL_0007:  ldloc.0

        IL_0008:  ldloc.1

        IL_0009:  add

        IL_000a:  ldloc.2

        IL_000b:  add

        IL_000c:  stloc.3

        IL_000d:  ldstr      'i+j+k='

        IL_0012:  ldloc.3

        IL_0013:  box        [mscorlib]System.Int32

        IL_0018:  call       string [mscorlib]System.String::Concat(object,

                                                                    object)

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

        IL_0022:  nop

        IL_0023:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()

        IL_0028:  pop

        IL_0029:  ret

      } // end of method Program::Main


      3、會用到的IL指令:


      nop:無操作


      ret:從當(dāng)前方法返回,并將返回值(如果存在)從調(diào)用方的計算堆棧推送到被調(diào)用方的計算堆棧上。

      call:調(diào)用由傳遞的方法說明符指示的方法。


      box:將值類轉(zhuǎn)換為對象引用,就是裝箱,同理可以知道拆箱unbox

       

      ldc.i4.X:把int32的值推送到計算堆棧


      stloc.X:把計算堆棧頂部的值放到調(diào)用堆棧索引為X處


      ldloc.X:把調(diào)用堆棧X處的值復(fù)制到計算堆棧


      4、理解注釋后的代碼


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

      {

        .entrypoint  //程序入口

        // 代碼大小       42 (0x2a)

        .maxstack  2    // 計算出計算堆棧的能存幾個值


        .locals init ([0] int32 i,

                 [1] int32 j,

                 [2] int32 k,

                 [3] int32 answer) //定義int32類型的i,j,k,answer


        IL_0000:  nop   //無操作


        IL_0001:  ldc.i4.1  //把i的值放到計算堆棧上

        IL_0002:  stloc.0   //把計算堆棧頂部的值(i的值)放到調(diào)用堆棧索引0處

        IL_0003:  ldc.i4.2  //把j的值放到計算堆棧上

        IL_0004:  stloc.1   //把計算堆棧頂部的值(j的值)放到調(diào)用堆棧索引1處

        IL_0005:  ldc.i4.3  //把k的值放到計算堆棧上

        IL_0006:  stloc.2   //把計算堆棧頂部的值(k的值)放到調(diào)用堆棧索引2處


        IL_0007:  ldloc.0   //把調(diào)用堆棧索引為0處的值復(fù)制到計算堆棧 

        IL_0008:  ldloc.1   //把調(diào)用堆棧索引為1處的值復(fù)制到計算堆棧

        IL_0009:  add       //相加

        IL_000a:  ldloc.2   //把調(diào)用堆棧索引為2處的值復(fù)制到計算堆棧

        IL_000b:  add       //相加

        IL_000c:  stloc.3   //把計算堆棧頂部的值(add的值)放到調(diào)用堆棧索引3處

        IL_000d:  ldstr      'i+j+k='  //推送對元數(shù)據(jù)中存儲的字符串的新對象引用。

        IL_0012:  ldloc.3   //把調(diào)用堆棧索引為3處的值復(fù)制到計算堆棧


        IL_0013:  box        [mscorlib]System.Int32     //裝箱

        IL_0018:  call       string [mscorlib]System.String::Concat(object,object)   //調(diào)用內(nèi)部方法

        IL_001d:  call       void [mscorlib]System.Console::WriteLine(string)       //調(diào)用WriteLine

        IL_0022:  nop       //無操作

        IL_0023:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()  //調(diào)用ConsoleKey

        IL_0028:  pop      //無操作

        IL_0029:  ret      //return

      } // end of method Program::Main


        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多