[CLR via C#]1.4 执行程序集的代码

原文:[CLR via C#]1.4 执行程序集的代码

1. 托管程序集同时包含元数据和IL。IL是与CPU无关的机器语言。可将IL是为一种面向对象的机器语言。

2. IL也是能使用汇编语言来写的,MicroSoft专门提供了一个名为ILAsm.exe的IL汇编器和一个名为ILDasm.exe的IL反汇编。

 

3. 高级语言只公开了CLR的所有功能的一个子集,IL汇编语言允许开发人员访问CLR的所有功能。如果你需要当前使用的语言不支持的CLR功能,可以使用IL语言或者其他CLR语言。

 

4. 为了执行一个方法,首先必须将它的IL转换成为本地CPU指令,这是CLR的JIT(just-in-time或"即时")编译器的职责。

 

5. 展示一个方法首次调用发生的事情。

在Main方法执行之前,CLR会检测出Main的代码引用的所有类型。这会使CLR分配一个内部数据结构,用于管理对所引用的类型的访问。

图1-4中,Main方法引用了一个Console类型(或就叫做Console类),这将让CLR分配一个内部结构。在这个结构中,Console类型定义的每个方法都有一个相对应的记录项。每一个记录项都容纳一个地址(但目前还是没有的,还没到这一步),根据地址即可找到方法的实现。

初始化CLR分配了一个内部结构,CLR将每个记录项都设置成包含在CLR内部的一个未文档化的函数(就理解成未公开的,只有微软自己清楚的函数)。姑且就将这个函数命名为JITCompiler(MSDN找不到这个函数,为了说明流程,自己取的函数名,因为真正的函数名微软没公开)

Main方法首次调用WriteLine时,JITCompiler也就被调用了。JIT函数负责将一个方法的IL代码编译成本地CPU指令。由于IL是"即时"编译的,所有通常将这个组件成为JIT编译器或JITter。

JITCompiler函数被调用时,它知道要调用的是哪个方法,以及具体是什么类定义了该方法。于是乎,JITCompiler会在定义该类型的程序集的元数据中查找被调用的方法的IL。

接着就是验证IL代码,并将IL编译成为本地CPU指令。本地CPU指令被保存到了一个动态分配的内存块中。

然后,JITCompiler在CLR为类型创建的内部数据结构,找到与被调用的方法对应的那一条记录项,修改最初对JITCompiler的引用,让它现在指向内存块(其中包括了刚才编译好的本地CPU指令)的地址。

最后,JITCompiler函数跳转到内存块中的代码,继续执行里面的具体的功能代码,这些代码执行完后,会返回到Main中,并像往常一样继续执行。

⑧现在,Main要执行第二个WriteLine方法了。这一次,由于第一次已对WriteLine的代码进行了验证和编译,所以会直接执行内存块中的代码,完全跳过JITCompiler函数。第二个WriteLine方法执行完毕,会再次返回Main。图1-5展示了第二次调用WriteLine时发生的事。

6. 对于大多数应用程序,因JIT编译造成的性能损失并不显著。大多数引用程序会反复调用相同的方法。看到上面,你对.NET的“第一次”是否有了颠覆性的认识了。

7. CLR的JIT编译器会对本地代码进行优化,代码优化后会获得更出色的性能。

9. IL是基于栈的。这就意味着它的所有执行都要将操作数压入(push)一个执行栈,并处栈弹出(pop)结果。

10. IL提供的最大优势在于应用程序的健壮性和安全性。将IL编译成CPU指令时,CLR会执行一个名为验证(verfication)的过程。这个过程会检查高级IL代码,确定代码所做的一切都是安全的。

11. C#编译器默认生成的是安全(safe)代码,这种代码是否安全是可验证的。然而,C#编译器也允许开发人员写不安全(unsafe)代码。

12. 不安全代码允许直接操作内存地址,并可操作这些地址处的字节,通常只有在与非托管代码进行互操作,或在提升效率极高的一个算法的性能时,才会这么做。

13.  MicroSoft提供一个名为PEverify.exe的好、程序,它检查一个程序集的所有方法,并报告其中含有不安全代码的方法。

时间: 2024-07-30 02:22:25

[CLR via C#]1.4 执行程序集的代码的相关文章

与动态执行的C#代码进行通讯

1.简介 能够动态执行 C# 代码是一件很酷的功能,比如,我们可以在控制台中输入一行 C# 代码,然后程序 自动编译并执行这一行代码,将结果显示给我们.这差不多就是一个最简单的 C# 代码解释器了. 动态执行 C# 代码又是一件很有用的功能,比如,我们可以将某些代码写在某个文件之中,由程序集 在执行时进行加载,改变这些代码不用中止程序,当程序再次加载这些代码时,就自动执行的是新代码了 . 下面,我将在写一个简单C# 代码解释器,然后将在 C# 代码解释器之中加入动态代码与解释器环境间 的动态交互

java中动态执行一段代码

动态|执行 动态的执行一段简单代码,采用生成java文件,调用javac编译,反射执行的方式. 只是一个简单测试,有些地方有待完善. 代码如下 -------------------------------------------------------------------------------- import java.io.*; /** * 动态执行一段代码(生成文件->编译->执行) * @author kingfish * @version 1.0 */public class

Windows编程:启动可执行(exe)程序 代码(C++)

通过输入程序位置启动可执行(exe)程序, 使用windows的CreateProcess()函数, 即可. 示例是调用预先生产的可执行(exe)程序. 代码: /* * main.cpp * * Created on: 2014.06.08 * Author: Spike */ /*vs 2012*/ #include <iostream> #include <windows.h> using namespace std; bool startProcess (const std

PHP cURL初始化和执行方法入门级代码

  这篇文章主要介绍了PHP cURL初始化和执行方法入门级代码,本文直接给出代码示例,代码中包含详细注释,需要的朋友可以参考下 这个是采集基础,最好熟悉一下 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 $ch = curl_init(); # 设定url和把结果返回,是否返回头部

在javascript中执行任意html代码的方法

关于javascript的eval()函数无法执行html代码的问题,下面为大家介绍下一种在javascript中执行任意html代码的方法,感兴趣的朋友不要错过 今天码代码中偶然发现有一种情况javascript的eval()函数无法执行html代码,比如:  代码如下: <script>eval('<li>hehe</li>')</script>    代码是不会执行的,但是改为如下就可以执行了:   代码如下: <script>eval('

aspnet mvc 拦截器 怎么不执行action的代码

问题描述 aspnet mvc 拦截器 怎么不执行action的代码 public class CheckCertAttribute : ActionFilterAttribute { /// /// 验证证书是否有效 /// public bool ValidCert { get; set; } /// /// 解析证书 /// public bool ResolveCert { get; set; } public override void OnActionExecuting(Action

plsql恢复存储过程包执行前的代码

问题描述 plsql恢复存储过程包执行前的代码 plsql恢复存储过程包执行前的代码,在存储过程包中写代码的时候由于手快,在删除代码后F8执行了下,撤销不回来.代码挺多的,希望大神解决. 解决方案 在线等答案 着急啦. 解决方案二: http://www.itpub.net/thread-1864534-1-1.html

jsp-Struts中有没有办法在渲染每个UI控件时都执行一段代码

问题描述 Struts中有没有办法在渲染每个UI控件时都执行一段代码 我有这么个需求:希望能通过数据库配置来指定每个页面上的每个UI控件是否最终显示出来.表结构例如: page | component_id | is_display 有什么办法能够加个拦截器之类的东西,在Struts渲染每个UI控件之前能执行这个拦截器,在拦截器里能取到当前被渲染的控件对象,并修改控件对象的属性吗? 我只知道Struts有Interceptor,但貌似只是拦截后台Action的,不知道是不是能处理UI控件. 请各

visual studio-关于Visual Studio执行闪现(代码执行窗口闪退)问题

问题描述 关于Visual Studio执行闪现(代码执行窗口闪退)问题 这是我的代码 看到问答解决方法(http://jingyan.todgo.com/shuma/2414656ctc.html),进入属性查看发现没有链接器,请大家帮助! 解决方案 嘛,一般执行是crtl+f5.......如果一闪而过的话可以加一个"getchar();"在return 的前面,还有,楼上的,vc这种东西就不要推荐了,最好还是gcc或者vs好一点 解决方案二: 在return 0的上面一行加sys