基于CLR(Common Languge Runtime)高级语言编译运行简解

48 篇文章 0 订阅

我们都知道.net号称跨语言的平台,原因就是在于由符合CLS规范的语言所书写的源代码,并非直接编译为汇编指令,而是编译为IL中间语言,再通过JIT即时编译器编译为机器语言进行执行。

拿C#举例,其过程就是:

C#源代码第一步编译,得到.netmodule模块文件,可以用VS命令行工具手动运行该编译过程(注意,需要先用dos命令切换到源代码路径位置),其指令为:

csc /t:module 源码一号名称.cs

C#源代码第二步编译,集成多个.netmodule模块文件,编译得到dll文件,所谓的增量编译,便是基于这个逻辑而来的,其指令为:

csc /t:labrary /addmodule:源码一号模块名称.netmodule 源码二号名称.cs

C#源代码第三步编译(如果你只是普通类库,则不再需要这一步编译,如果你提供了程序入口,那么就需要这一步编译来生成exe可执行文件),通过给dll文件指定程序入口,生成exe可执行文件,其指令为:

csc /out:要生成的名称.exe /t:exe /r:被引用的程序集一号.dll /r:被引用的程序集二号.dll 程序入口源代码.cs

注意:在第三步编译命令之中,其中(/t:exe)入参意为编译成CUI(控制台)执行文件,如果是GUI(窗体界面)执行文件,则使用(/t:winexe)。另外,在VS一键式编译过程中,模块编译的过程发生在obj文件夹之下,之后再进行合并编译至bin文件夹之下。

好了,经过上述的几个编译过程,我们便得到了dll类库文件或者exe执行文件了,其中dll、exe文件是由程序集清单+多个.netmodule托管模块文件+资源文件(如果需要的话)共同组成的。

其中,程序集清单包含着该程序集的自描述信息。资源文件无非是一些图标、图片、文本信息等。而托管模块主要由以下部分组成:PE文件头、CLR头、元数据(Metedata)、中间语言(IL)文件。其中元数据以数据表的形式存放着该托管模块的详细描述性信息,包括类、属性、方法、引用等等等等。而中间语言文件,就是中间语言的代码,我们可以用ildasm反编译工具来进行查看。通过阅读中间语言代码,我们可以得知C#等高级语言的执行逻辑本质,可以刨开那些优雅语法糖的层层外衣了解执行原理,对我们去深层次理解高级程序语言有极大的帮助。

那么既然程序集中的代码指令是IL中间语言,那么如何让计算机去执行呢?很显然,计算机读不懂中间语言,那么这个时候就需要JIT登场了。JIT(Just-In-Time Compiler)即时编译器,用来将中间语言编译为机器指令,我们都知道,CPU的硬件标准各有不同,很显然一种JIT不能满足所有的编译需求,所以每一种规格的CPU,都有其相应的JIT。

那么到底什么是即时编译器呢?重点就在即时二字上面,即时即时,说白了就是现用现译,用到哪里译到哪里,是动态的。而与之相对应的,便是静态编译,一次编译,永久使用。显然,静态编译虽然执行效率最高,但对处理器更新是极其不友好的,所以多用于硬件稳定的情况之下。

那么即时编译器既然是动态的,它是如何知道自己要编译哪些中间代码呢?整个.net类库如同汪洋大海一般,浩瀚无边,是谁为JIT指路的呢?

答案就是:元数据(Metedata)

之前我们说程序集结构的时候就已说过,程序集是由清单、多个模块、资源文件等组成,而其中的模块便是包含元数据和IL两部分。而元数据,又切实描述着程序集自身,包括他的类型、字段、属性、特性、方法以及最重要的:他引用了谁?他继承于谁?

程序编译之时,由CLR提供的基本组件之一Class Loader将Metadata和IL从PE文件中取出,并加载到运行时内存。Class Loader作用正像其名称所宣扬的那样,load一个Class给CLR,然后由JIT编译该类的执行方法所指向的方法IL代码。

那么至此,从编写源代码,到机器执行这个大过程,便逐渐清晰了。

编译过程:由高级语言编译为模块(包含元数据和中间语言),再集成多模块编译为dll文件,最终结合程序入口编译为可执行文件。

执行过程:由程序入口进入,以模块元数据为指导顺藤摸瓜进行JIT即时编译,用到哪里,译到哪里。

以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值