- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
通过MSIL了解CLR的运行原理 发布者: sorke? 来自: 转载? 时间: 2004-7-12 15:55:25? 查看: 575次
作为.NET最低层次的公共基础,微软中介语言(MSIL或IL)对一般开发者具有非常重要的意义。除了好奇心以外,仔细研究应用程序的IL能让你更为清楚地了解到公共语言运行时(CLR)执行高级C#或VB.NET代码的基本原理,从而有助于你发现和解决一些比较细微的问题。在这篇文章里,我将引领读者了解IL,学习有关的一些关键指令,同时对CLR的操作机理做一点基础性解释。我不打算教你用IL编程,而是分析一些IL语法和语句使你对IL有更多了解。
ILDASM简介
微软的IL拆卸实用程序Ildasm.exe(通常位于\Program Files\Microsoft.Net\FrameworkSDK\Bin目录下)可以析构.NET assembly(装配)、根据你的要求从程序中抽取IL代码。对某一assembly调用该使用程序后,ILDASM会给出该assembly中所有类和名称空间的一个视图,如图A所示:
图A
ILDASM浏览assembly
当你进到某个类的成员或其方法,ILDASM就会为你显示该成员的IL代码。如果之前你曾经看到过汇编器或J++字节码,那么IL可能在你看来会觉得有点眼熟。在另一方面,如果你仅对抽象的高级程序语言有所了解,那么IL看起来更像是胡言乱语。
好,现在你知道如何窥视assembly的IL代码了,但这些代码都意味着什么呢?在回答这个问题之前,首先让我们先来了解下CLR的有关知识。
虚拟CPU
对.NET程序来说,.NET CLR在功能上就如同一块虚拟的CPU,它执行IL代码、操作数据。CLR和真实的CPU类似之处在于它们都不直接操作内存中的变量而是使用程序变量的临时拷贝,CLR把这些程序变量存放在堆栈上。从内存拷贝某个变量到堆栈的行为称做装载(loading),而从堆栈拷回某个变量到内存的行为则被称做存储(storing)。
所以把两个数字相加的过程应该是这样的:
1.装载第1个数字并把它推入堆栈。
2.装载第2个数字并把它推入堆栈。
3.从堆栈中取出这两个数字并把它们相加。
4.把结果存储到内存。
什么是堆栈?
理解IL的关键是知道堆栈的工作原理。堆栈是一种抽象数据结构,其操作机理是后进先出。当你把新条目推进堆栈时,已经在堆栈内的任何条目都会压到堆栈的深处。同样的,把一个条目从堆栈移出则会让堆栈内的其他条目都向堆栈的顶部移动。只有堆栈最顶端的条目能从堆栈中取出,条目离开堆栈的顺序和它们被推进堆栈的顺序一样。你不妨回想下自动售货机的装货和取货过程就明白了。
重要的IL语句
既然你已经明白了CLR操作的基础知识,下面我们就接着讨论你面前的那些代码。怎么?没有看到什么代码?那么请你看看这里列出的IL代码。
你首先看见的是对当前方法的IL声明,其中包括方法的名字,返回类型、参数列表以及附着于该方法的其他修饰关键词(static/shared、public、virtual等等)。对象构造器则被赋给一个特殊的名字:.ctor。
在IL中,方法参数按照它们在参数列表中的位置依次被引用。如果方法是静态或共享方法,那么参数0则是参数列表中的第1个参数。而对实例方法来说,参数0则是指向该方法所在类的实例的指针(Me或者this)。方法中的所有局部变量都在.locals标记的段落中以同样的方式声明。
在声明所有的局部变量以后,程序的实际正文才开始。每条IL指令,或opcode都可以根据你的喜好以一个IL_ 标记作为代码行开头。我们接下来再了解些更重要的IL指令。
变量用法
以LD开头的指令把变量从内存装载到堆栈供其操作。装载指令有若干条,每一条装载指令都操作特定类型的变量。以下就是其中的一些装载指令:
LDC把一个数字常数装入堆栈。这条指令有两个修饰词。第一个是类型标识符,第二个是实际的数值。
LDLOC把一个局部变量装入堆栈。另外还有一条LDLOCA指令把一个局部变量的地址(而非变量的内容)装入堆栈。变量由它们在.locals节的位置标识。这些指令装载位置4及以后位置使用不同的语法,但是索引号会出现在指令中。
LDARG装载成员的一个参数,而LDARGA指令则装载参数的地址。变量由它们在.locals节中的位置标识。这些指令装载位置4及以后位置使用不同的语法,但是索引号仍然出现在指令中。
LDELEM把数组元素装入堆栈而且通常先于表示这个索引的其他装载语句之前使用。
LDLEN把一个数组的长度装入堆栈。
LDFLD和LDSFLD把类域(成员变量)和静态类域装入堆栈。域由一个全名识别。
每一条装载指令都有对应的一条存储指令,后者以ST开头,负责把一个条目存入内存。例如,ST
文档评论(0)