如何加载通用语言运行时?

  • 我们可以在%windir%system32下查找MSCorEE.dll文件来判断一个机器中是否安装了.NET框架。
  • 当生成一个.exe程序集时,编译器/链接器会产生一些特殊的信息,并将它们嵌入到结果程序集的PE文件表头及其各个组成文件的.text部分。当EXE文件被调用时,这些特殊的信息将导致CLR被加载并初始化。CLR随后会定位到应用程序的入口点方法,从而以此来启动应用程序。

      .NET程序的生成以及执行过程:

      将源代码(source code)编译成为托管模块(Managed Module)-->将托管模块组合成程序集-->加载CLR-->执行程序集代码

       一、将源代码编译为托管模块

   我们可以用任何支持CLR的编程语言来创建源代码文件,然后用相应的编译器来做语法检查和源代码分析,最终生成托管模块。托管模块是一个需要CLR才能执行的标准Windows可移植可执行(portable executable,简称PE)文件。  

      二、将托管模块组合成程序集

   CLR并不直接和模块打交道,它直接打交道的是程序集(assembly)。

   对于程序集,简言之,有如下特点:

   A.程序集是一个或多个托管模块,以及一些资源文件的逻辑组合。

   B.程序集是组件复用,以及实施安全策略和版本策略的最小单位。    

      三、加载CLR

      主要分为托管EXE加载CLR和托管DLL加载CLR。

      EXE文件加载CLR的过程:

    托管EXE文件被调用时,Windows先加载该文件,发现其.idata部分记录了要把MSCorEE.dll(微软组件对象运行时执行引擎)加载到进程的地址空间(编译器在生成托管EXE文件时,x86 stub函数JMP _CorExeMain被嵌入到了PE文件的.text部分,而这个函数是从MSCorEE.dll中导入的,所以.idata部分会记录 MSCorEE.dll).加载了MSCorEE.dll后,加载器获得_CorExeMain函数的地址,同时修正托管EXE中的stub函数的JMP 指令。进程的主线程开始执行修正后的x86 stub函数,该函数会跳转到_CorExeMain函数上,_CorExeMain函数开始初始化CLR,并查看可执行程序集的CLR表头以确定要执行的托管入口点方法。随后IL代码被翻译成本地CPU指令。CLR跳转到编译后的本地CPU指令上,至此,托管应用程序开始真正运行。

      托管DLL加载CLR的过程类似,分为非托管代码加载托管DLL和托管代码加载托管DLL

      非托管代码加载托管DLL:

   1、Windows加载托管DLL,并自动加载MSCorEE.dll,获取MSCorEE.dll中_CorDllMain函数的地址,并修正托管DLL中x86 stub函数的JMP指令。

   2、调用LoadLibrary加载托管DLL的线程将跳到x86 stub函数上来,该函数会跳转到MSCorEE.dll中的_CorDllMain函数上。_CorDllMain函数开始初始化CLR,然后立即返回,应用程序也返回到正常状态继续执行。

     注:托管DLL中方法的IL代码只会在非托管代码明确调用时开始以即时编译的方法执行。

     托管代码加载托管DLL:

     调用代码会检查托管DLL中的元数据,然后以即时编译的方式执行其内方法的IL代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值