zoukankan      html  css  js  c++  java
  • 读懂IL代码(三)

    由于要写毕业论文的缘故,最近比较没有时间写,总是要抽出时间抽出时间。诶,这样的生活比较烦躁。

    这一篇主要写委托、类、方法的IL代码,一一来说明。

    委托:搞过C#的都应该清楚,委托实际上是一个类。编译器会把它编译成一个类,继承自MulticastDelegate的类,里面有三个方法,BeginInvoke,EndInvoke和Invoke,当我们使用委托方法名进行调用方法时,编译器内部实际上是调用了Invoke方法(语法糖)。

    以下就用简单的代码来掩饰一下委托的IL代码

    先来看看编译器把委托编译成什么样子:

    好啦,下面就是重要的IL代码啦,其实大家可以先自己去尝试解析一下,我觉得当自己去尝试某些东西的话,会记得更牢一些。

    看到上面的代码,是否有的指令非常熟悉,我觉得大部分的指令我们在前面两篇都有讲过了,不过在这里我还是一句一句的解释

    .method private hidebysig static void Main(string[] args)cilmanaged
    {
        .entrypoint //入口啦,这个说过很多次了。
        .maxstack 2 //评估堆栈可能容纳数据项的最大个数。
        .locals init (
            [0] class TestDemo4.Program/MyDele dele) //上面已经讲过了,委托最终是编译成类的,所以这里是一个类类型的变量dele,存储在调用栈。
        L_0000: nop //No Operation。
        L_0001: ldnull //将空引用推送到计算堆栈上。
        L_0002: ldftn void TestDemo4.Program/UserInfo::PrintName(string) //将指向实现特定方法的本机代码的非托管指针(native int类型)推送到计算堆栈上,也就是指将方法指针压入评估栈中。
        L_0008: newobj instance void TestDemo4.Program/MyDele::.ctor(object, native int)//创建委托实例并压入评估栈中。这一步会调用委托的构造函数(.ctor),这个构造函数需要两个参数,一个是对象引用,这里就是L_0001:ldnull:空对象,第二个参数是方法的地址L_0002中的动作。
        L_000d: stloc.0 //将评估栈中的委托实例保存到调用栈的第0个位置上。
        L_000e: ldloc.0 //获取调用栈中第0位置的值(委托实例),并压入评估栈中。
        L_000f: ldstr "Helius" //加载字符串,在托管堆中创建Helius对象,并把引用存放在评估栈上。
        L_0014: callvirt instance void TestDemo4.Program/MyDele::Invoke(string) //Invoke,看到没,委托实例调用了Invoke的的方法来执行。callvirt只能调用实例方法和虚方法,不能调用静态方法
        L_0019: nop //No Operation
        L_001a: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //调用ReadKey方法。
        L_001f: pop //清空评估栈。
        L_0020: ret //return。
    }
    

    --------------------------------------------------------------------------------分割线------------------------------------------------------------------------------------------------

    类与方法的常规代码:

    这里先从Person类开始解析,这里我使用到了自动属性,大家应该也都很明了,编译器把自动属性编译成了一个私有字段和两个方法。

     OK啦,又到了看Main函数的IL代码时间了

    上面的IL代码中,只有一个指令在之前没有出现过,那就是newobj这个指令,这个指令的意思是创建一个实例对象,并将实例对象的引用推送到计算堆栈上,也就是评估栈上。

    我不想一句一句的解析了,我现在就用画图的形式来解释一下实例化一个类的过程:

    其实我这里也只是泛泛之谈而已,我觉得大家完全有必要自己写一个小Demo,编译完之后使用Reflector看一下IL代码,这样子会更清晰一些。而且有不懂的地方,我觉得大家完全可以自行百度或者拿出来让大家讨论一下。

    下一章再讲一下流程控制的IL代码后,我想应该就可以结束掉这部分内容了。

    
    
    
  • 相关阅读:
    Mysql基础(十二):sql语句执行步骤详解(一)准备工作
    JVM 专题二十三:面试题(一)
    leetcode算法题基础(三十八) 并查集(二)547. 朋友圈
    leetcode算法题基础(三十七) 并查集(一)200 岛屿数量
    leetcode算法题基础(三十六)动态规划(四)91. 解码方法
    leetcode算法题基础(三十五)动态规划(三)5. 最长回文子串
    leetcode算法题基础(三十四)动态规划(二)121. 买卖股票的最佳时机
    Virtio-vsock Device + aF_UNIX 套接字通信
    Using the Firecracker Virtio-vsock Device + F_UNIX 套接字通信
    vhost-user
  • 原文地址:https://www.cnblogs.com/Helius/p/5299217.html
Copyright © 2011-2022 走看看