在.net平台下基于C#语言生成的IL代码,我们主要学习的就是C#语法下生成什么样的IL代码和IL指令含义和执行逻辑;看过很多博客写的有关IL文章,对指令解释不够详细,现在我结合我的学习心得和大家一起分析一下IL几个常用指令。如果你是刚了解clr和IL的爱好着,请仔细阅读以下文字。
-
首先先介绍一下记忆体
下面这段源自网上文章资料,我觉得这些介绍够我们今天讨论,有关于托管堆计算栈和调用栈的详细内容有机会我想详细讨论,因为这哥仨始终贯穿的IL执行过程,尤其是加入线程之后讨论点更多了。
1、Managed Heap:這是动态配置(Dynamic Allocation)的记忆体,由 Garbage Collector(GC)在执行時自動管理,整個Process 共用一個 Managed Heap。
2、Call Stack:這是由 .NET CLR 在执行時自動管理的记忆体,每個 Thread 都有自己专属的 Call Stack。每呼叫一次 method,就会使得Call Stack 上多了一個 Record Frame;呼叫完毕之后,此 Record Frame 会被丢弃。一般來說,Record Frame 內记录着 method 参数(Parameter)、返回位址(Return Address)、以及区域变数(Local Variable)。Java VM 和 .NET CLR 都是使用 0, 1, 2… 编号的方式來識別区别变数。
3、Evaluation Stack:這是由 .NET CLR 在执行時自動管理的记忆体,每個 Thread 都有自己专属的 Evaluation Stack。前面所謂的堆叠式虚拟机器,指的就是這個堆叠。
-
结合实例讨论IL
上面介绍的三个记忆体,我们这里只讨论call stack和Evaluation stack,首先执行CLR托管代码时要找到入口Main方法,然后JIT将会编译这些指令,JIT编译的对象永远是方法内部的指令,至于程序集,命名空间,类这些结构和逻辑咱们暂且先交给.net,至于是怎么编译成机器码的也先不管。
这里我们先讨论指令是怎么用记忆体的,上面介绍到方法在调用时会用到call stack,在上面创建一个栈帧(Record Frame ),里面存了啥上面上也介绍了,每个方法被调用时都会创建一个栈帧,关键是为什么用栈帧呢,因为方法调用时有参数,方法里面有局部变量,这些东西总需要一个空间来存的,而且方法在调用完之后这个栈帧会被丢弃,讲到这里是不是有种似曾相识的感觉,你们在学语法的时候老师是不是也是这么讲的,现在我们从CLR的角度再来理解会更清晰。在说一下,Call stack中的区域变数,这个东西就是存方法局部变量的地方(重要且常用,想想在C#里局部变量是不是很常用),其访问方式将在下面代码中介绍。
总结一下:call stack 是个方法调用时用的栈,且线程专属,栈的特点后进先出,调用一个方法创建一个栈帧,方法里面还调用了方法会再创建一个栈帧,也就是在栈的顶部压入一个栈帧,栈帧丢弃要在该方法结束后执行,也就是当前方法里面调用的其他方法还没结束你需要等待,因为对应的你的栈帧上面还有栈帧,而出栈永

最低0.47元/天 解锁文章
4937





