zoukankan      html  css  js  c++  java
  • 【IL】IL入门

    1.IL基本介绍

    1.1 CLR介绍

    在介绍IL之前,先说一说CLR。CLR的全称Commen Language Runtime 公共语言运行时。因为CLR的存在,使得多语言开发成为可能。下面给出一张图片,解释支持CLR的几种语言的关系。

    从上面的图片可以看出,CLR其实是不关心开发人员用哪一种语言写源代码。这意味着在选择编程语言时,应该选择最容易表达自己意图的语言。可用任何一种语言开发代码,只要编译器是面向CLR的就可以了。

    Microsoft创建了好几种面向CLR的语言编辑器,包括:C/C++、C#、Visual Basic、F#、Iron Python、Iron Ruby、IL编辑器,当然面向CLR的语言绝不止Miscrosoft提供的这几种。

    在上面的图片,有一点值得提出,IL编译器也是面向CLR的。虽然最终CLR会把托管模块中的IL代码编译成本机CPU指令,但是IL编译器本身也是面向CLR的,所以可以直接利用IL进行开发。查看 如何对C#程序进行反编译,获得更详细的内容。

    1.2 IL介绍

    在上面介绍CLR概念的时候,知道了IL也是面向CLR的,IL的全称是中间代码(intermediate code),也称为托管代码(managed code)。所有面向CLR的编译器,最终都会把相应的代码编译为托管模块。注意,高级语言通常只公开了CLR全部功能的一个子集,然而,IL汇编语言是允许开发人员访问CLR的全部功能的,例如:C++编译的托管模块,希望能够在C#程序中调用,但是C++和C#可能由于支持的功能不一样,在C#中有可能不会成功调用,反之,C#的程序可能在C++中也不会 成功调用,无论怎样IL是支持的,也就是说IL是能够全部访问所有CLR功能的。如果在开发中,遇到一种语言不能解决的问题,可以考虑使用另一种语言,或是使用IL语言。

    2.IL案例讲解

    在这里笔者使用C#作为源代码:

    static void Main(string[] args)
    {
                int num = 1;
                int num2 = 2;
                int num3 = 3;
                Console.WriteLine(num+num2+num3);
    }

    IL代码为:

    //hidebysig指令表示如果当前类为父类,用该指令标记的方法将不会被子类继承
    //cil managed表明方法体中的代码是IL代码,且是托管代码,即运行在CLR运行库上的代码
    .method private hidebysig static void Main(string[] args)cil managed
    {
        .entrypoint //该指令代表该函数程序的入口函数。每一个托管应用程序都有且只有一个入口函数,CLR加载程序时,首先从.entrypoint函数开始执行。
        .maxstack 2 //执行构造函数时,评估堆栈可容纳数据项的最大个数。评估堆栈是保存方法中所需要变量的值的一个内存区域,该区域在方法执行结束时会被清空,或者存储一个返回值。
        .locals init (
            [0] int32 num,
            [1] int32 num2,
            [2] int32 num3) //表示定义int类型的变量,变量名分别为num,num2,num3。存储在调用栈。
        L_0000: nop  //No operation的意思,即没有任何操作。
        L_0001: ldc.i4.1  //将“1”压入评估栈,此时“1”处于评估栈的栈顶。
        L_0002: stloc.0  //此指令表示把值从评估栈中弹出,并赋值给调用栈的第0个变量num。
        L_0003: ldc.i4.2 
        L_0004: stloc.1 
        L_0005: ldc.i4.3 
        L_0006: stloc.2 //从.locals init到L_0006,相当于C#代码的为i,j,k赋值。
        L_0007: ldloc.0  //取调用栈中位置为0的元素压入评估栈(取i的值)。
        L_0008: ldloc.1  //取调用栈中位置为1的元素压入评估栈(取j的值)。
        L_0009: add  //做加法操作
        L_000a: ldloc.2 //取调用栈中位置为2的元素压入评估栈(取k的值)。
        L_000b: add  //做加法操作
        L_000c: call void [mscorlib]System.Console::WriteLine(int32) //调用输出方法
        L_0011: nop  //No Operation
        L_0012: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //调用ReadKey方法
        L_0017: pop //把评估栈的内容清空
        L_0018: ret  //return 标记返回值
    } //Main方法结束

    观察上面的IL代码,可以发现,汇编语言和高级语言的不一样之处,在汇编语言中,声明一个变量,首先要把变量名存储, 然后把值压入到栈堆中,最后把值弹出并且赋值给相应的变量。关于Il的指令详细,可以查看  IL指令详解。

  • 相关阅读:
    ti processor sdk linux am335x evm setup.sh hacking
    ti processor sdk linux am335x evm Makefile hacking
    导出Excel数据
    使用dom4j解析XML例子
    java解析xml文件并输出
    java解析xml文件
    java解析XML获取城市代码
    drop.delete.trauncat的区别
    hibernate 中id生成策略
    如何使java中double类型不以科学计数法表示
  • 原文地址:https://www.cnblogs.com/HDK2016/p/8605735.html
Copyright © 2011-2022 走看看