一切从IL开始

Posted 齐大圣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一切从IL开始相关的知识,希望对你有一定的参考价值。

IL是什么?

  IL是Intermediate Language的缩写,是.Net代码转化成机器语言的一个中间语言,因此又把IL语言称之为反汇编语言。

 

IL工具有哪些?

  俗话说,工欲善其事必先利其器。了解IL就要首先从使用工具开始。在.Net世界里有数个不同的IL工具,包含编译器和反编译器。最经典的编译和反编译利器就是.Net Framework自带的ILASM.exe和ILDASM.exe工具,同时还有其他,例如Reflector.exe,ILSay.exe等等。

 

具体IL指令介绍

  要了解IL的指令,我们以一个非常简单的程序开始,源代码如下:

using System;

namespace HelloWorld
{
    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

相信大家对这段代码再熟悉不过,对于编译后的可执行文件应用ILDasm.exe反编译工具,还原为文本MSIL编码,编译后的IL结构中,包含了MANIFEST和HelloWorld类,如下图所示:

 

其中MANIFEST是附加信息表,主要包含了程序集的一些属性,例如程序集名称、版本号、哈希算法、程序集模块等等,以及对外部引用程序集的引用项;下面我们重点根据Hello World类来介绍IL指令

  首先是Hello World类型,IL代码如下:

  >.class表明了HelloWorld是一个类,该类型继承自外部程序集mscorlib的System.Object类。

  >public为访问控制权限,表示具有最高的访问权限,为访问成员没有限制。

  >auto表示程序加载时内存的布局是有CLR决定的,而不是程序本身。

  >.ansi属性则为了在没有被托管和被托管的代码之间实现无缝转换。没有被托管的代码,值的是没有运行在CLR运行库之上的代码,例如原来的C,C++代码等。

  >.beforefieldinit属性为HelloWorld提供一个附加信息,用于标记运行库可以在任何时候执行类型构造函数方法,只要该方法在第一次访问其静态字段之前执行即可。如果没有beforefieldinit则运行库必须在某个精确时间执行构造函数方法,从而影响性能优化。

  然后是.ctor方法,代码如下:

  

  >.cil managed说明方法体中为IL代码,指示编译器编译为托管代码。

  >.maxstack表明执行构造函数.ctor期间的评估堆栈可容纳数据项的最大个数。关于评估堆栈,其用于保存方法所需变量的值,并在方法执行结束时清空,或者存储一个返回值。

  >.IL_0000,是一个标记码行开头,一般来说,IL_标记之前的部分为变量的声明和初始化。

  >.ldarg.0(ldarg即load argument)表示装载第一个成员参数,在实例方法中值的是当前实例的引用,该引用将用于积累构造函数中调用。

  >.call指令一般用于调用静态方法,因为静态方法是在编译期指定的,而在此处call并非调用静态方法,而是构造函数.ctor(),也是在编译期指定的;而另一个指令callvirt则表示调用实例方法,它的调用过程有异于call,函数的调用时在运行时确定的,首先会检查被调用函数是否为虚函数,如果不是就直接调用,如果是则向下检查子类是否有重现,如果有就调用重写实现,如果没有还调用原来的函数。

  >.ret表示执行完毕,返回。

 

  最后是Main方法,代码如下:

  

  >.entrypoint指令表明了CLR加载程序HelloWorld.exe时,是首先从.entrypoint方法开始执行的,也就是表明Main方法将作为程序的入口函数。没有托管程序必须有且只有一个入口程序。这区别于将Main函数作为程序入口标志。

  >.ldstr(即load string)指令表示将字符串压栈,“Hello World!”字符串将被移到stack顶部。CLR通过从元数据表中获取文字常量来构造string对象。

  >.hidebysig属性用于表示如果当前类作为父类时,类中的方法不会被子类继承。因此HelloWorld子类中不会看到Main方法。

  >.关于注释,IL代码中注释和C#等高级语言的注释相同。

 

参考:

《你必须知道的.Net》

 

以上是关于一切从IL开始的主要内容,如果未能解决你的问题,请参考以下文章

动手写IL到Lua的翻译器——准备

读懂IL代码就这么简单

转载读懂IL代码就这么简单

如何创建具有较低完整性级别 (IL) 的新流程?

通过IL Emit来创建类型的探究

IL2CPP 详解