zoukankan      html  css  js  c++  java
  • 一切从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》

  • 相关阅读:
    linux远程桌面连接 VNC Server
    linux内核 mtd分区
    STC15控制数码管 38译码器
    DS12C887实时时钟
    printf打印字节调试
    LED 控制卡 单元板 接口引脚定义
    linux守护进程start-stop-daemon启动服务
    相机速率计算
    CodeWarrior IDE烧写介绍
    让 Web 站点崩溃最常见的七大原因
  • 原文地址:https://www.cnblogs.com/qianxingdewoniu/p/5618817.html
Copyright © 2011-2022 走看看