当前位置:必发365电子游戏 > 操作系统 >      IL代码是怎么样
     IL代码是怎么样
2019-12-19

 怎样解读IL代码

     关于IL代码,作者有将从多少个方面去揭发它神秘的面纱。IL代码是什么?大家怎么要去读懂IL代码?大家怎么样去读懂IL代码?那八个难题的解答,将是自个儿解读IL代码的黄金时代体化思路。

     IL代码是何等?IL(Intermediate Language),它也叫做CIL也许MSIL,翻译成中文正是“中间语言”。C#的JIT编写翻译器能够将C#源程序编写翻译为.exe或.dll文件,但此刻编写翻译出来的程序代码并不是CPU能一向施行的二进制代码,而是轶事中的IL代码。因而,.exe或许.dll文件都得以被VS安装自带的ILDASM展开,查看IL代码。

    我们为啥要去读懂IL代码?无论领悟哪一门本事,大家都应有从其本质出发,探明最大旨的运作机理,最终有效地领会和垄断(monopoly卡塔尔(英语:State of Qatar)它。对于C#言语来讲,掌握IL语言就犹如抓住了C#语言的庐山面目目,它可以有效地支援大家去领会编写翻译器的运维机理。对于有些C#金牌来说,深刻地研商IL语言后,能对IL语言直接开展校正后编写翻译。但就本人当下的水准,读懂IL代码是为着更加深刻地驾驭C#各类风味,举个例子C#中最主要的部分着力特征,委托、事件。

   大家又将如何去读懂IL代码?在读懂IL代码在此之前,作者必须要先给大家介绍一下,C#代码编写翻译情状下的内存构造。就自己日前已知分为5大块内部存款和储蓄器区。分别为,托管堆,线程货仓,总计栈,调用栈,代码区。

   托管堆(Managed Heap):寄存援用类型的多少,引用类型的多少由GC(Garbage Collection)负担管理。

   线程仓库(Thread Heap Stack卡塔尔:存放值类型的数目和引用类型地址,值类型的数码由操作系统直接担任管理。

   总结栈(Evaluation Stack):有的时候寄存值类型的数量和引用类型之处的货仓。相符先进后出(FILO)基本栈准则。

   调用栈(Call Stack):在那之中的Record Frame用于寄存.locals init(int32 V_0卡塔尔国指令的参数值,是一个有的变量表,不切合先进后出(FILO)基本栈准绳。

   代码区(Code):寄放各类程序指令集。

    数据内部存款和储蓄器区有4个,按等第能够分开成3个等第。托管区为最高档,唯有存放援用类型数据;线程货仓为第二级,存放值类型数据与援引类型地址;计算栈和调用栈为第三级,在线程中调用方法时,重要在那四个栈中操作数据。要看懂IL代码第一步就是急需分明地问询总括栈与调用栈相互操作数据的涉及。上面笔者将引进二个IL代码实例来证实多少个内部存款和储蓄器区是哪些相互操作数据的。

    C#源代码

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();
}
}
}

IL代码

.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint //程序入口
// 代码大小 42 (0x2a卡塔尔(英语:State of Qatar)
.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的值卡塔尔(قطر‎放到调用仓库索引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_     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) //调用WriteLine
IL_0022: nop //无操作
IL_0023: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //调用ConsoleKey
IL_0028: pop //无操作
IL_0029: ret //return
} // end of method Program::Main

      总计:1.ldloc.0前缀ld,load含义载入,即压入总结栈;loc,locals含义调用栈,即取值于调用栈第0位参数。

              2.其余的ld前缀都以取值于线程仓库。比方ldc.i4.0,ldstr,ldfld,ldfld。

              3.st前缀,store含义存款和储蓄,即弹出总括栈。弹出的值贮存于调用栈。

          基于上述3条结论,大家基本能够看懂超过半数IL代码的点子内部总计栈和调用栈的数码交互作用。在随后的博文中,笔者会呈报一下什么通过IL代码去深切了然委托、事件。希望大家能够支持一下。

下一篇:没有了