小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

詳解.NET IL代碼

 走出塵埃 2016-12-19

一、前言

IL是什么?

 Intermediate Language (IL)微軟中間語言

C#代碼編譯過程?

C#源代碼通過LC轉為IL代碼,IL主要包含一些元數據和中間語言指令;

JIT編譯器把IL代碼轉為機器識別的機器代碼。如下圖

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

MSIL的作用:MSIL包含一些元數據和中間語言指令

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

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

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

為什么要了解IL代碼?

如果想學好.NET,IL是必須的基礎,IL代碼是.NET運行的基礎,當我們對運行結果有異議的時候,可以通過IL代碼透過表面看本質;

IL也是更好理解、認識CLR的基礎;

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

二、如何把ILDasm導入到VS中

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

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

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

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

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

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

三、分析IL代碼

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

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

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

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

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

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

1、用C#寫一個簡單控制臺應用程序

using System;namespace ILDemo{ class Program { staticvoid 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代碼如下:

.methodprivatehidebysig static void Main(string[] args) cilmanaged{ .entrypoint // 代碼大小 42 (0x2a).maxstack2.localsinit ([0] int32 i, [1] int32 j, [2] int32 k, [3] int32 answer) IL_0000:nopIL_0001:ldc.i4.1IL_0002:stloc.0IL_0003:ldc.i4.2IL_0004:stloc.1IL_0005:ldc.i4.3IL_0006:stloc.2IL_0007:ldloc.0IL_0008:ldloc.1IL_0009:addIL_000a:ldloc.2IL_000b:addIL_000c:stloc.3IL_000d:ldstr'i+j+k='IL_0012:ldloc.3IL_0013:box [mscorlib]System.Int32 IL_0018:callstring [mscorlib]System.String::Concat(object, object) IL_001d:callvoid [mscorlib]System.Console::WriteLine(string) IL_0022:nopIL_0023:call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() IL_0028:popIL_0029:ret} // end of method Program::Main

3、會用到的IL指令:

nop:無操作

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

call:調用由傳遞的方法說明符指示的方法。

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

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

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

ldloc.X:把調用堆棧X處的值復制到計算堆棧

4、理解注釋后的代碼

.methodprivatehidebysig static void Main(string[] args) cilmanaged{ .entrypoint//程序入口// 代碼大小 42 (0x2a).maxstack2// 計算出計算堆棧的能存幾個值.localsinit ([0] int32 i, [1] int32 j, [2] int32 k, [3] int32 answer) //定義int32類型的i,j,k,answerIL_0000:nop//無操作IL_0001:ldc.i4.1//把i的值放到計算堆棧上IL_0002:stloc.0//把計算堆棧頂部的值(i的值)放到調用堆棧索引0處IL_0003:ldc.i4.2//把j的值放到計算堆棧上IL_0004:stloc.1//把計算堆棧頂部的值(j的值)放到調用堆棧索引1處IL_0005:ldc.i4.3//把k的值放到計算堆棧上IL_0006:stloc.2//把計算堆棧頂部的值(k的值)放到調用堆棧索引2處IL_0007:ldloc.0//把調用堆棧索引為0處的值復制到計算堆棧 IL_0008:ldloc.1//把調用堆棧索引為1處的值復制到計算堆棧IL_0009:add//相加IL_000a:ldloc.2//把調用堆棧索引為2處的值復制到計算堆棧IL_000b:add//相加IL_000c:stloc.3//把計算堆棧頂部的值(add的值)放到調用堆棧索引3處IL_000d:ldstr'i+j+k='//推送對元數據中存儲的字符串的新對象引用。IL_0012:ldloc.3//把調用堆棧索引為3處的值復制到計算堆棧IL_0013:box [mscorlib]System.Int32 //裝箱IL_0018:callstring [mscorlib]System.String::Concat(object,object) //調用內部方法IL_001d:callvoid [mscorlib]System.Console::WriteLine(string) //調用WriteLineIL_0022:nop//無操作IL_0023:call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //調用ConsoleKeyIL_0028:pop//無操作IL_0029:ret//return} // end of method Program::Main

四、最后

IL是跟我高級架構經理的分享和博客園相關的博客學習總結的,最后留2個題目,也是我的高級架構經理分享中提到的兩個好玩的問題,也能看出對IL的掌握的程度

 答案后續(xù)公布。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多