久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

淺析.NET MSIL代碼

 weijianian 2016-08-07


來(lái)源:Joye.Net

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


一,、前言


IL是什么?


 Intermediate Language (IL)微軟中間語(yǔ)言


C#代碼編譯過(guò)程,?


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


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



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


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


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


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


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


為什么要了解IL代碼,?


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


IL也是更好理解,、認(rèn)識(shí)CLR的基礎(chǔ);


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


二,、如何把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代碼通過(guò)ILDasm反編譯后(左圖),ILDasm圖標(biāo)意義(右圖)


  



三,、分析IL代碼


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



圖片來(lái)源:https://msdn.microsoft.com/zh-tw/library/dd229210.aspx

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


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


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


可以對(duì)照IL指令:指令列表,,一步一步來(lái)分析IL代碼


1、用C#寫一個(gè)簡(jiǎn)單控制臺(tái)應(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打開(kāi)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、會(huì)用到的IL指令:


nop:無(wú)操作


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

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


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

 

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


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


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


4、理解注釋后的代碼


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

{

  .entrypoint  //程序入口

  // 代碼大小       42 (0x2a)

  .maxstack  2    // 計(jì)算出計(jì)算堆棧的能存幾個(gè)值


  .locals init ([0] int32 i,

           [1] int32 j,

           [2] int32 k,

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


  IL_0000:  nop   //無(wú)操作


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

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

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

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

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

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


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

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

  IL_0009:  add       //相加

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

  IL_000b:  add       //相加

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

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

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


  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       //無(wú)操作

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

  IL_0028:  pop      //無(wú)操作

  IL_0029:  ret      //return

} // end of method Program::Main


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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多