原文:[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的好、程序,它检查一个程序集的所有方法,并报告其中含有不安全代码的方法。

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

  1. 【.net 深呼吸】跨应用程序域执行程序集

    应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...

  2. 执行C#动态代码

    执行C#动态代码 using System; using System.Data; using System.Configuration; using System.Text; using Syste ...

  3. Entity Framework 6 Recipes 2nd Edition(12-1)译 -> 当SaveChanges( ) 被调用时执行你的代码

    第12章定制EF 在本章的小节里,定制实体对象和EF处理的一些功能.这些小节将涵盖很多”幕后”的事情,能让你的代码更加统一解决一些事情,比如用一个业务规则中心统一地为实体执行验证. 本章开始的小节,将 ...

  4. EntityFramework 7 如何查看执行的 SQL 代码?

    EF 其他版本:EntityFramework 如何查看执行的 SQL 代码? 在 EF7 中,并没有 Context.Database.Log 属性访问方式,但改变更加强大了,我们可以使用下面方式配 ...

  5. EntityFramework 如何查看执行的 SQL 代码?

    在 VS 调试的时候,如果我们项目中使用的是 EntityFramework,查看 SQL 执行代码就不像 ADO.NET 那样直观了,我们需要设置下,可以参考下: How can I log the ...

  6. Unity 延迟执行一段代码的较为优雅的方式

    在Unity中,延时执行一段代码或者一个方法或者几个方法的情况非常普遍. 一般会用到Invoke和InvokeRepeating方法.顾名思义,第一个是执行一次,第二个是重复执行. 看下定义: voi ...

  7. SQL Server安全(6/11):执行上下文与代码签名(Execution Context and Code Signing)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...

  8. 第六篇 SQL Server安全执行上下文和代码签名

    本篇文章是SQL Server安全系列的第六篇,详细内容请参考原文. SQL Server决定主体是否有必要的执行代码权限的根本途径是其执行上下文规则.这一切都可能复杂一个主体有执行代码的权限,但是却 ...

  9. [转]Unity 延迟执行一段代码的较为优雅的方式

    Unity中,延时执行一段代码或者一个方法或者几个方法的情况非常普遍. 一般会用到Invoke和InvokeRepeating方法.顾名思义,第一个是执行一次,第二个是重复执行. 看下定义: void ...

随机推荐

  1. React-Native入门

    React-Native入门指导之iOS篇 React-Native 入门指导系列教程目录 一.准备工作 (已完成) 二.项目介绍与调试 三.CSS样式与Flex布局 四.常用UI控件的使用 五.JS ...

  2. [webapi] 如何在查看api时 显示api的说明

    首先在Controller的方法中 写上相关注释,如下图 然后 右击webapi项目点属性.按照下图选择 红色框中内容要保持一致 然后保存. 在项目中找到到这个文件Areas/HelpPage/App ...

  3. Freedur为什么免费?

    难道没有人看到他们官方网站权? Freedur倒闭了...... 一个中国人.Chris Lee,作为Freedur的会计师.窃取了公司的银行帐号.并将Freedur的官方站点指向自己的空间. 而且声 ...

  4. 编写ruby扩展库

    # Loads mkmf which is used to make makefiles for Ruby extensions require 'mkmf' # Give it a name ext ...

  5. 【原创】构建高性能ASP.NET站点之三 细节决定成败

    原文:[原创]构建高性能ASP.NET站点之三 细节决定成败 构建高性能ASP.NET站点之三 细节决定成败 前言:曾经就因为一个小小的疏忽,从而导致了服务器崩溃了,后来才发现:原来就是因为一个循环而 ...

  6. Jg-Table 过程1 (jgTable)

    近期使用Table,他写了一.时间紧急.还有一点简单的无精写作.但主要的功能已经支持, 大家有时间可以看看,欢迎吐槽 jg-table 1.0                 1. 支持固定头角    ...

  7. Unity3d 导入图像尺寸失真解决方案

    导入到unity3d内的图像被默认长宽变换为满足2^n关系. 例如以下图,我有张图片名称为984plus598表示我尺寸为984*598.拷贝到unity3d中后的大小为1024*512 方法一: 在 ...

  8. Git常用操作汇总(转)

    如果一个文件被删除了,可以使用切换版本号进行恢复.恢复方法: 先确定需要恢复的文件要恢复成哪一个历史版本(commit),假设那个版本号是: commit_id,那么 git checkout com ...

  9. iptables惹的祸

    我的工作环境总是一台Mac机+在Mac机上跑的虚拟机(Virtual Box) 有一个错误我总是在犯:宿主机总是无訪问到虚拟机里的web服务. 解决方法也非常easy:那就是关闭虚拟机上的防火墙!!! ...

  10. Java Date API demo

    package date; import java.text.DateFormat; import java.util.Calendar; import java.util.Date; /*2015- ...