上一篇提到了最基本的IL代码,应该是比较通俗易懂的,所以有了上一篇的基础之后,这篇便要深入一点点的来讲述了。

首先我必须再来说一些重要的概念:

Evaluation Stack(评估栈):这是由.NET CLR在执行时候自动管理的记忆体,每一个线程都有自己的评估栈,也就是说,它是用来存储临时变量的线程栈(应该可以这么理解)。值类型存储数据,引用类型存储地址。

Call Stack(调用栈):这也是由.NET CLR在执行时候自动管理的记忆体,每一个线程都有自己的调用栈,每一次调用method,就会产生一个栈帧(stack frame),当方法结束的时候,此栈帧就会被丢弃。

大家一定疑问怎么都是栈呀,堆到哪里去了嘞,大家别急,下面说:

Managed Heap:这是动态配置的记忆体,由Garbage Collector(GC)执行时自动管理,整个程序共用一个。我把这个理解为托管堆,用来存储引用类型的值。

这一篇主要是以引用类型为主来讲述IL代码。

大家都知道把值类型变成引用类型是采用装箱的操作,所以这里也先说一下装箱的过程:

(1)内存分配,在Managed Heap(托管堆)中分配一个内存空间;

(2)将值类型的字段拷贝到分配的内存中;

(3)将托管堆中的对象地址返回给新的对象,Over。

以上是一些基本知识点,现在主要来讲解IL代码:

正规代码如下:

我用Reflector进行查看IL代码:

上图就是IL代码了,经过上一篇的介绍,我觉得这里大家应该也看得懂吧,下面我就来解释这段IL代码吧。

.method private hidebysig static void Main(string[] args)cilmanaged
{
.entrypoint //入口
.maxstack 2 //评估栈可容纳数据项的最大个数。
.locals init (
[] string str,
[] int32 num) //定义并初始化参数,并存入局部变量表(Call Stack)中。
L_0000: nop //No Operation
L_0001: ldstr "Helius" //将字符串“Helius”压入评估栈中。
L_0006: stloc.0 //将字符串从评估栈中弹出,赋值给局部变量表的第0个变量。
L_0007: ldc.i4.s 0x1b //解析:int类型的数值大小不一样,IL代码也是不一样的。比如int i=-1;IL代码为ldc.i4.M1;当i的值大于等于9的时候,IL代码就为ldc.i4.s(i的十六进制表示形式),当i的值小于等于-2时,IL代码表示为ldc.i4.s(i)。
L_0009: stloc.1 //将值从评估栈中弹出,赋值给局部变量表的第1个变量。
L_000a: ldloca.s num //取出局部变量表中num的值“27”并压入评估栈中。
L_000c: call instance string [mscorlib]System.Int32::ToString() //从评估栈中取出数值“27”,调用ToString方法转成string类型并将引用存入评估栈中。
L_0011: ldloc.0 //取出局部变量表中的第0个位置元素值“Helius”,并压入评估栈,(此时评估栈中有两个值,字符串“Helius”和“27”的引用地址)。
L_0012: call string [mscorlib]System.String::Concat(string, string) //调用String类的Concat方法把字符串拼接并存入托管堆中,把引用地址返回给评估栈。
L_0017: call void [mscorlib]System.Console::WriteLine(string) //调用输出方法,调用输出方法后评估栈中的值(指向托管堆中字符的地址)会被回收。
L_001c: nop
------------------------------------------分割线---------------------------------------------------------------------------------------------------
L_001d: ldloc.1 //取局部变量表中的第1个位置参数num值,存入评估栈中。
L_001e: box int32 //把num值27装箱,并返回托管堆中的地址存入评估栈中。
L_0023: ldloc.0 //去局部变量表中的第0个参数,并压入评估栈中。
L_0024: call string [mscorlib]System.String::Concat(object, object)//弹出评估栈中两个值,并调用String的Concat方法把字符拼接,存入托管堆中,并返回引用地址到评估栈中。
L_0029: call void [mscorlib]System.Console::WriteLine(string) //调用输出方法。
L_002e: nop
L_002f: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()//调用ReadKey方法
L_0034: pop //把评估栈的内容清空
L_0035: ret //return 标记返回
} 以图来解释上面的例子可能更明白一点(程序员学会画图很重要,我记得去面试的时候,面试官还叫我画项目的架构图):
图1
图2
图3

从以上的图中可以明显看出调用方法与装箱的流程。引用类型都是存放在托管堆里面的,而栈只存放引用类型的地址,这点是要特别注意的。

下一篇我会写方法,委托和类的IL代码解析。

读懂IL代码(二)的更多相关文章

  1. 读懂IL代码就这么简单(二)

    一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...

  2. 【转载】读懂IL代码就这么简单(二)

    一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...

  3. 读懂IL代码就这么简单(三)完结篇

    一 前言 写了两篇关于IL指令相关的文章,分别把值类型与引用类型在 堆与栈上的操作区别详细的写了一遍 这第三篇也是最后一篇,之所以到第三篇就结束了,是因为以我现在的层次,能理解到的都写完了,而且个人认 ...

  4. 读懂IL代码就这么简单 (一)

    一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...

  5. 读懂IL代码就这么简单

    原文地址:http://www.cnblogs.com/zery/p/3366175.html 一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不 ...

  6. 读懂IL代码就这么简单 ---- IL系列文章

    读懂IL代码就这么简单 (一) 读懂IL代码就这么简单(二) 读懂IL代码就这么简单(三)完结篇 出处:http://www.cnblogs.com/zery/tag/IL%20%E7%B3%BB%E ...

  7. 【转载】读懂IL代码就这么简单(三)完结篇

    一 前言 写了两篇关于IL指令相关的文章,分别把值类型与引用类型在 堆与栈上的操作区别详细的写了一遍这第三篇也是最后一篇,之所以到第三篇就结束了,是因为以我现在的层次,能理解到的都写完了,而且个人认为 ...

  8. 【转载】读懂IL代码就这么简单 (一)

    一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...

  9. 读懂IL代码(一)

    以前刚开始学C#的时候,总有高手跟我说,去了解一下IL代码吧,看懂了你能更加清楚的知道你写出来的代码是如何运行互相调用的,可是那时候没去看,后来补的,其实感觉也不晚.刚开始看IL代码的时候,感觉非常吃 ...

随机推荐

  1. Java_xml_Dom解析方式

    本博文为子墨原创,转载请注明出处! http://blog.csdn.net/zimo2013/article/details/12094775 1.Node准备 Node接口是整个文档对象模型的主要 ...

  2. vijosP1901学姐的钱包

    题目:https://vijos.org/p/1901 题解:这题比较有意思. 经过一番思考之后我想出了下面的算法: 我们反着来推,按i从大到小 f[i]表示从>=m到 i 需要多长时间,则如果 ...

  3. 转 ---- Asp.net mvc项目分页功能

    1.定义一个分页用的Page<T>类 1 /* 使用示例: 2 var pager = new Pager<Article>( 3 this.ControllerContext ...

  4. .net开源工作流引擎ccflow

    关于济南驰骋信息技术有限公司的.net开源工作流引擎 驰骋工作流引擎,工作流程管理系统:简称ccflow,驰骋一体化解决方案简称ccport. ccflow是济南驰骋信息技术有限公司向社会提供的一款1 ...

  5. AMBA总线介绍

    The Advanced Microcontroller Bus Architecture (AMBA) specification defines an on- chip communication ...

  6. ITU-R BT.656 协议

    ITU-R BT.601和ITU-R BT.656国际电信联盟(International Telecommunication Union)无线通信部门(ITU-R)制定的标准.严格来说,ITU-R ...

  7. Docker入门实战_正版电子书在线阅读_百度阅读

    Docker入门实战_正版电子书在线阅读_百度阅读 Docker入门实战

  8. FastDfs 说明、安装、配置

    fastdfs是一个开源的,高性能的的分布式文件系统,他主要的功能包括:文件存储,同步和访问,设计基于高可用和负载均衡,fastfd非常适用于基于文件服务的站点,例如图片分享和视频分享网站 fastf ...

  9. hdu4431 Mahjong 枚举搜索。。

    japanese麻将什么玩意..都没有豪华七对... 没什么难的 就是枚举搜索了 分三种类型的胡牌 f1是七对 f2是十三幺 f3是普通的胡牌 就先找一对 再找三个三个的 就是一直超时..在峰峰的指导 ...

  10. Eclipse下Tomcat常用设置

    Eclipse下Tomcat常用设置 1,Eclipse建立Tomcat服务 1.1 新建Server 首先这里是指,jee版的Eclipse.Eclipse是没有像MyEclipse那样集成Tomc ...