读懂IL代码(三)
由于要写毕业论文的缘故,最近比较没有时间写,总是要抽出时间抽出时间。诶,这样的生活比较烦躁。
这一篇主要写委托、类、方法的IL代码,一一来说明。
委托:搞过C#的都应该清楚,委托实际上是一个类。编译器会把它编译成一个类,继承自MulticastDelegate的类,里面有三个方法,BeginInvoke,EndInvoke和Invoke,当我们使用委托方法名进行调用方法时,编译器内部实际上是调用了Invoke方法(语法糖)。
以下就用简单的代码来掩饰一下委托的IL代码

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

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

看到上面的代码,是否有的指令非常熟悉,我觉得大部分的指令我们在前面两篇都有讲过了,不过在这里我还是一句一句的解释
.method private hidebysig static void Main(string[] args)cilmanaged
{
.entrypoint //入口啦,这个说过很多次了。
.maxstack 2 //评估堆栈可能容纳数据项的最大个数。
.locals init (
[] 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代码后,我想应该就可以结束掉这部分内容了。
读懂IL代码(三)的更多相关文章
- 读懂IL代码就这么简单(三)完结篇
一 前言 写了两篇关于IL指令相关的文章,分别把值类型与引用类型在 堆与栈上的操作区别详细的写了一遍 这第三篇也是最后一篇,之所以到第三篇就结束了,是因为以我现在的层次,能理解到的都写完了,而且个人认 ...
- 【转载】读懂IL代码就这么简单(三)完结篇
一 前言 写了两篇关于IL指令相关的文章,分别把值类型与引用类型在 堆与栈上的操作区别详细的写了一遍这第三篇也是最后一篇,之所以到第三篇就结束了,是因为以我现在的层次,能理解到的都写完了,而且个人认为 ...
- 读懂IL代码就这么简单(二)
一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...
- 读懂IL代码就这么简单 (一)
一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...
- 读懂IL代码就这么简单
原文地址:http://www.cnblogs.com/zery/p/3366175.html 一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不 ...
- 读懂IL代码就这么简单 ---- IL系列文章
读懂IL代码就这么简单 (一) 读懂IL代码就这么简单(二) 读懂IL代码就这么简单(三)完结篇 出处:http://www.cnblogs.com/zery/tag/IL%20%E7%B3%BB%E ...
- 【转载】读懂IL代码就这么简单(二)
一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...
- 【转载】读懂IL代码就这么简单 (一)
一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...
- 读懂IL代码(四)
这一篇是IL系列的最后一篇的,主要是要说一下IL中的流程控制.我相信,经过前面三篇的介绍,看IL代码应该不是什么大问题了吧.好吧,闲话不多说了,就来简单的说一下吧. 还是跟前几篇一样,以例子来解释说明 ...
随机推荐
- Devexpress之popupMenu
1.拖放一个BarManager控件barManager1和一个PopupMenu控件popupMenu1 2.设置popupMenu1的Manager属性为barManager1 3.拖放一个Tex ...
- HDU- 2265 Encoding The Diary
Encoding The Diary Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU-1390 Binary Numbers
http://acm.hdu.edu.cn/showproblem.php?pid=1390 Binary Numbers Time Limit: 2000/1000 MS (Java/Others) ...
- bootstrap easyUI 的选型
最近开始搭建新的项目后台,开始在Bootstrap 和 EasyUI两个框架上选型,个人还是倾向于Bootstrap,毕竟这个响应式效果是个趋势,并且可以自动兼容不同的屏幕分辨率和设备.
- [CODEVS1220]数字三角形
题目描述 Description 如图所示的数字三角形,从顶部出发,在每一结点可以选择向左走或得向右走,一直走到底层,要求找出一条路径,使路径上的值最大. 输入描述 Input Description ...
- Java Servlet 工作原理问答
导读 本文来自stackoverflow的问答,讨论了Java Servlet的工作机制,如何进行实例化.共享变量和多线程处理. 问题:Servlet是如何工作的?Servlet 如何实例化.共享变量 ...
- MAC 下安装PIL
1. 安装使用 pip install pil 结果报如下错误 Collecting PIL Could not find a version that satisfies the requireme ...
- NIO组件Selector详解
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...
- C#基础知识—父类和子类的关系
基础知识一: using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms ...
- 使用val()方法设置表单中的默认选中项
有时候我们展示给用户的表单中的checkbox,radio,selec等标签的一些项是默认选中的.比方:当用户改动文章的时候,假设相应的栏目为下拉框的话,那么它的默认选中值应该是原来的栏目位置. 能够 ...