三、加载公共语言运行时中介绍了在安装了.Net Framework中加载公共语言运行时,公共语言运行时加载程序集的过程.以及通过vs stdio设置源码编译的目标平台的过程.

本问主要介绍公共语言加载完程序集之后,执行程序集中的代码的过程.

一、IL中间语言

1、IL简介

一、源代码-面向CLR的编译器-托管模块-(元数据&IL代码)中介绍了C#源代码通过C#编译器生成的最终产物是托管模块,而托管模块是由IL中间语言和元数据组成,IL语言是比大多数机器语言都要高级的语言,IL有以下功能:

(1)、能访问和操作对象类型

(2)、提供了指令创建和初始化对象

(3)、调用对象上的虚方法和操作数组

(4)、提供了抛出和捕捉异常的指令实现错误处理

......等等

因此,可将IL视为一种面向对象的机器语言.

2、IL通识

(1)、我们一般通过C#或者F#或者Visual Basic来编程,然后编译器将它们编译成IL,然后IL和其他机器语言一样,也可以使用汇编语言来编写,MS提供了ILAsm.exe的IL汇编器和ILDasm.exe的反汇编器.

(2)、通常高级语言只提供CLR全部功能的一个子集,然而IL汇编语言允许开发人员方法CLR的全部功能,如果你选择的编程语言隐藏了一个你迫切需要的功能,那么你可以使用IL汇编语言来实现,或者使用另一种编程语言来实现

3、CLR执行一个方法时发生的事情

(1)、第一次执行

(2)、第二次执行

如果Main方法第二次调用Console的WriteLine方法,会完全跳过JITComliler函数,因为第一次已经执行和初始化过了,会执行执行内存块中的代码,执行完毕有返回值,则返回到Main(),没有返回值,则跳转带Main方法,进行下一步操作.

注:方法只有在第一次运行时会有JIT进行IL验证和IL编译成本机代码造成的性能损失,以后对该方法的调用都已本机代码的形式全速运行,无需验证IL代码并把它编译成本地代码.

4、CLR执行方法时的IL和验证

(1)、IL基于栈

它的所有指令要将操作数压入一个执行栈,并从栈中弹出(pop)结果。由于IL没有提供操作寄存器的指令,所有人们很容易的创建新的语言和编译器,生成面向CLR的代码.

(2)、IL指令"无类型"

例:IL提供了Add指令将压入栈的最后的两个操作数加到一起.add指令不分32位和64位版本.当add指令执行时,它判断栈中的操作数的类型,并执行恰当的操作.

(3)、IL指令最大的优势

IL最大的优势并不是对底层的抽象,而是应用程序的健壮性和安全性.将IL编译成本机CPU指令时,CLR会检查验证高级IL代码,确定代码所做的一切操作都是安全的.

例如:会核实调用的每个方法都有正确数量的参数,传给每个方法的每个参数都有正确的类型,每个方法的返回值都得到了正确的使用,每个方法都有一个返回语句.

注:托管模块的元数据包含验证过程要用到的所有方法及类型信息.

(4)、IL验证对进程产生的影响

windows的每个进程都有自己的虚拟地址空间,独立空间存在的是因为不能简单的信任一个应用程序的代码。应用程序完全可能读写无效的内存地址。将每个Windows进程都放到独立的地址空间,将获得健壮性和稳定性,一个进程干扰不到另一个进程.

通过验证托管代码,可以确保代码不会不正确地访问内存,不会干扰另一个应用程序的代码.这样就可以放心地将多个托管应用程序放到同一个Windows虚拟地址空间运行。

注:由于windows进程需要大量的操作系统资源,所以进程数量太多,会损害性能并制约可用的资源。用一个进程运行多个应用程序,减少进程,增强性能,减少所需的资源,健壮性没有丝毫下降,这是托管代码的优势之一.

CLR提供了在一个操作系统进程中执行多个托管应用程序的能力,每个应用程序都在一个AppDomain中执行,每个托管Exe文件默认都在它自己的独立地址空间中运行,这个地址空间已有一个AppDomain.

注:IIS和SQL Server可实现在一个进程中运行多个AppDomain.

5、CLR执行不安全的代码

C#编译器默认生成安全的代码,代码的安全性可以验证,然而C#编译器也允许开发人员写不安全的代码,不安全的代码允许直接操作内存,并可操作这些地址处的字节。这是一个很强大的功能,不过一般是在提升一个对效率要求极高的算法的时候使用。

然而,使用不安全的代码存在重大风险,这种代码可能会破坏数据结构,危害安全性,甚至造成新的安全漏洞,所以,C#编译器要求不安全的代码都使用unsafe关键字标记.

注:当JIT编译器编译一个unsafe方法时,该程序集必须有System.Security.Permissions.SecurityPermission权限.且System.Security.Permissions.SecurityPermissionFlagd的SkipVerification的标志是否设置,如果设置了,JIT编译器会便宜unsafe的代码.

MS提供了PEVerify.exe的程序,用它检查一个程序集的所有方法,并报告其中不安全代码的方法.

6、实现IL代码验证的技术

JIT验证IL代码时.必须要访问所有以来的程序集中包含的元数据.例如:当PEVerify检查程序集时,它必须能够定位并加载应用的所有的程序集.

CLR是采用和平时执行程序集时一样的绑定和探测规则来定位程序集.

四、CLR执行程序集中代码和IL代码简介的更多相关文章

  1. MSIL入门(一)C#代码与IL代码对比

    基础概念 Microsoft中间语言(MSIL),也成为通用中间语言(CIL),是一组与平台无关的指令,由特定于语言的编译器从源代码生成.MSIL是独立于平台的,因此,他可以在任何公共语言基础架构支持 ...

  2. 读懂IL代码(一)

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

  3. C#基础拾遗系列之一:先看懂IL代码

    一.前言 首先,想说说为什么要写这样系列的文章,有时候在和同事朋友聊天的时候,经常会听到这样的话题: (1)在这家公司没什么长进,代码太烂,学不到东西.(你有没有想想框架为什么这样写,代码还可以怎么去 ...

  4. C# 如何查看源程序的IL代码

    1.打开microsoft  visual  studio  2008  /  visual  studio  tools /  visual  studio  2008 命令提示  ,并输入ilda ...

  5. 如何解读IL代码

    如何解读IL代码 关于IL代码,我有将从三个方面去揭开它神秘的面纱.IL代码是什么?我们为什么要去读懂IL代码?我们如何去读懂IL代码?这三个问题的解答,将是我解读IL代码的整体思路. IL代码是什么 ...

  6. 一、源代码-面向CLR的编译器-托管模块-(元数据&IL代码)

    本文脉络图如下: 1.CLR(Common Language Runtime)公共语言运行时简介 (1).公共语言运行时是一种可由多种编程语言一起使用的"运行时". (2).CLR ...

  7. CLR Via第一 章 知识点整理(3)CLR执行程序集的IL代码

    在了解CLR运行之前让我们先简单了解一下IL 除了编译器编译的IL代码,IL也是一种汇编语言,也就是说我们可以直接编写IL代码,当然也有对应的IL编译器,值得一提的是对于面向CLR的其他语言,CLR只 ...

  8. CLR基础,CLR运行过程,使用dos命令创建、编译、运行C#文件,查看IL代码

    CLR是Common Language Runtime的缩写,是.NET程序集或可执行程序运行的一个虚拟环境.CLR用于管理托管代码,但是它本身是由非托管代码编写的,并不是一个包含了托管代码的程序集, ...

  9. 【计算机基础】IL代码-CLR平台上的字节码【什么是字节码?它与虚拟机的关系?】

    字节码(英语:Bytecode)将虚拟机可以读懂的代码称之为字节码.将源码编译成虚拟机读的懂的代码,需要虚拟机转译后才能成为机器代码的中间代码 叫做字节码. 字节码主要为了实现特定软件运行和软件环境. ...

随机推荐

  1. idea使用svn提交时出现错误Warning not all local changes may be shown due to an error

    参考于https://www.cnblogs.com/zhujiabin/p/6708012.html 解决方案: 1.File > Settings > Version Control ...

  2. 山东省第七届ACM竞赛 J题 Execution of Paladin (题意啊)

    题意:鱼人是炉石里的一支强大种族,在探险者协会里,圣骑士有了一张新牌,叫亡者归来,效果是召唤本轮游戏中7个已死鱼人.如果死掉的不足7个,那么召唤的数量就会不足7. 鱼人有很多,下面的4个是: 寒光智者 ...

  3. noip第8课作业

    1.     计算书费 [问题描述]下面是一个图书的单价表: 计算概论 28.9 元/本 数据结构与算法 32.7 元/本 数字逻辑 45.6元/本 C++程序设计教程 78 元/本 人工智能 35  ...

  4. MFC中不同对话框间使用SendMessage发送自定义消息的具体实现

    1. 基本知识 SendMessage的基本结构如下: SendMessage(     HWND hWnd,  //消息传递的目标窗口或线程的句柄.     UINT Msg, //消息类别(这里可 ...

  5. hdu 5023 线段树+状压

    http://acm.hdu.edu.cn/showproblem.php?pid=5023 在片段上着色,有两种操作,如下: 第一种:P a b c 把 a 片段至 b 片段的颜色都变为 c . 第 ...

  6. PHP Functions - arsort()

    <?php $characters = array('a','b','c','d','e','f'); arsort($characters); print_r($characters); /* ...

  7. 设计模式之命令模式(Command Pattern)

    一.什么是命令模式? 命令模式,封装了方法调用细节,以解耦请求者与执行者,具体流程如下: 1.从请求者(客户)的角度看 请求者(客户)发出请求 -> 调用者(系统)构造命令对象封装请求 -> ...

  8. 【原创】Self-Contained Container(自包含容器)

    自包含容器是一种自包含的结构,很有趣.需要使用模板类,但只有在模板类型是该类的子类时,才使该类具有自包含的结构.这种结构从数据结构的角度看比较有用.通常的树类中的模板通常是“数据”的概念,即模板不参与 ...

  9. Extjs文件上传问题总结

    本来文件上传是一个简单而常用的功能,但是,由于刚刚接触extjs,对extjs中的控件及其使用方法并不熟悉,导致本来一个很快就可以搞定的文件上传问题,弄了将近两天的时间.现将问题及解决办法发出来,供有 ...

  10. (一)Mahapps安装与使用

    一.Mahapps安装 1.NuGet程序包安装 右击项目-->选择 “管理Nuget程序包”-->搜索“MahApps.Metro” 2.包管理控制台 选择“工具”-->“NuGe ...