精华内容
下载资源
问答
  • 1.8 C-Minus:编译器项目的一种语言 18 练习 19 注意与参考 20 第2章 词法分析 21 2.1 扫描处理 21 2.2 正则表达式 23 2.2.1 正则表达式的定义 23 2.2.2 正则表达式的扩展 27 2.2.3 程序设计语言记号的正则表达式 29...
  • 正如于渊在本书结尾所说“我们写自己操作系统是出于一种好奇,或者说一种求知欲。我希望这样不停地‘过把瘾’能让这种好奇不停地延续”。 好奇心是动力源泉,追究问题本质是优秀黑客必备素质,只有充分...
  • 正如于渊在本书结尾所说“我们写自己操作系统是出于一种好奇,或者说一种求知欲。我希望这样不停地‘过把瘾’能让这种好奇不停地延续”。 好奇心是动力源泉,追究问题本质是优秀黑客必备素质,只有充分...
  • windows上可编译Linux内核

    热门讨论 2011-09-15 15:54:39
    修改了Trans.cpp中的一个dug,该dug在translate MinGW gcc编译的程序时可能会出错。用MinGW gcc 编译的程序的VirtualAddress的形式可能是0xFFC1000这样的形式,其实0x1000才是它的VirtualAddress 08/4/2 修改了下...
  • 在tests文件夹查找当今可以使用的更多Pika代码示例。 有关计划功能的演示,请参见demo.pk # Syntax is similar to Standard ML, but comments use # # Pika doesn't have universes, so Type has type Type val ...
  • 修改了Trans.cpp中的一个dug,该dug在translate MinGW gcc编译的程序时可能会出错。用MinGW gcc 编译的程序的VirtualAddress的形式可能是0xFFC1000这样的形式,其实0x1000才是它的VirtualAddress 08/4/2 修改了下...
  • Java目录监视器源程序 9个目标文件 内容索引:JAVA源码,综合应用,目录监视 用JAVA开发的一个小型的目录监视系统系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录文件大小及文件增减数目的变化。...
  • 使用表现层框架则可以将Jsp剩余的JavaBeans完全分离,这部分JavaBeans主要负责显示相关信息,一般是通过标签库(Taglib)实现,不同框架有不同自己的标签库,Struts是应用比较广泛的一种表现层框架。 2、 Ajax...
  • 代码语法错误分析工具pclint8.0

    热门讨论 2010-06-29 07:00:09
    PC-Lint是C/C++软件代码静态分析工具,你可以把它看作是一种更加严格编译器。它不仅可以检查出一般语法错误,还可以检查出那些虽然符合语法要求但不易发现潜在错误。 C语言灵活性带来了代码效率提升,但...
  • 微软中间语言—MSIL(转载)

    千次阅读 2010-09-09 09:32:00
    在.Net框架,公共语言基础结构...MSIL是将.Net代码转化为机器语言的一中间过程。它是一种介于高级语言和基于Intel的汇编语言的伪汇编语言。当用户编译一个.Net程序时,编译器将源代码翻译成一组可以有效地转换为本

    在.Net框架中,公共语言基础结构使用公共语言规范来绑定不同的语言。通过要求不同的语言至少要实现公共类型系统(CTS)包含在公共语言规范中的部分,公共语言基础结构允许不同的语言使用.Net框架。因此在.Net框架中,所有的语言(C#,VB.Net,Effil.Net等)最后都被转换为了一种通用语言:微软中间语言(MSIL)。

    MSIL是将.Net代码转化为机器语言的一个中间过程。它是一种介于高级语言和基于Intel的汇编语言的伪汇编语言。当用户编译一个.Net程序时,编译器将源代码翻译成一组可以有效地转换为本机代码且独立于CPU 的指令。当执行这些指令时,实时(JIT)编译器将它们转化为CPU特定的代码。由于公共语言运行库支持多种实时编译器,因此同一段MSIL代码可以被不同的编译器实时编译并运行在不同的结构上。从理论上来说,MSIL将消除多年以来业界中不同语言之间的纷争。在.Net的世界中可能出现下面的情况:一部分代码可以用Effil实现,另一部分代码使用C#或VB完成的,但是最后这些代码都将被转换为中间语言。这给程序员提供了极大的灵活性,程序员可以选择自己熟悉的语言,并且再也不用为学习不断推出的新语言而烦恼了。

    解密微软中间语言的系列文章将通过一些简单易懂的方式来揭示中间语言的复杂原理。这些原理通过详细的例子来阐述。在一些例子中同时给出了源代码和中间代码,通过比较源代码和中间代码,我们可以更好地理解编译器的局限性,指导我们编写出更好更快的代码。

     

    微软中间语言概述

    1.用中间语言编写的一个简单程序

    让我们从经典的Hello World例子开始。首先在一个文本编辑器中输入以下的代码,并保存为HelloWorld.il:

     

    .assembly HelloWorldIL {} .method static void HelloWorld() { .entrypoint ldstr "Hello World." call void [mscorlib]System.Console::WriteLine(class System.String) ret }

    在一个中间语言程序中,如果某一行以“.”开始,则代表这是一个传输给汇编工具的指令,该指令要求汇编工具执行某些操作,例如生成一个函数或类。而没有以“.”开始的行是中间语言的代码。在中间语言中方法通过汇编命令method来定义,汇编命令后跟方法的返回值、名称和参数。方法体被包含在{}中。例子中的ret代表该方法的结束。

    一个中间语言文件可以包含很多函数,汇编工具没有办法分辨应该首先执行哪一个方法。在诸如C#或VB这一类高级语言中,程序的入口方法通常都有特定的名称,例如在C#中的public static void Main()。这就是上面的汇编工具发出错误提示的原因。在中间语言中,第一个被执行的方法被称为入口函数(EntryPoint Function)。为了告诉汇编工具HelloWorld是入口函数,我们需要在代码中增加一条汇编命令entrypoint,该命令可以放在方法体中的任何位置。需要注意的是在一个程序集中只能有一个入口函数。

    中间语言代码通常被编译成一个模块,该模块隶属于一个程序集。在.Net中模块和程序集的概念非常重要,因此开发人员需要很清楚地了解它们。在后面的文章中我们将详细讨论.Net程序的结构。通过在代码中加入assembly命令,可以告诉汇编工具中间代码隶属于那个程序集。assembly命令的格式如下:

     

    .assembly <程序集名称> {}

    需要注意在method命令后加入了static关键字,这是因为每个入口函数必须是静态的,例如在C#中我们将Main方法定义为public static void Main()。

    接下来我们需要调用WriteLine方法将HelloWorld字符串输出到屏幕。通过使用call指令(Instruction)我们可以达到这个目的。指令的格式如下:

     

    call <return type> <namespace>.<class name>::<method name>

    这里我们可以看到当调用一个方法时,中间语言和其他的编程语言有很大的区别。在中间语言中,如果需要调用一个方法,需要指定方法的全名,包括他的名称域(namespace)、类名、返回值类型和参数的数据类型。这样就保证了汇编工具能够找到正确的方法。

    在调用WriteLine方法时需要一个字符串参数。所有传递给方法或函数的参数都被保存在内存的堆栈中。在中间语言中有一个指令ldstr可以从堆栈中加载一个字符串。(堆栈是内存中的一块区域,它被用于将参数传输给方法,在后面我们会详细讨论堆栈的问题)。所有的方法都从堆栈中获取它们的参数,因此ldstr指令是必不可少的。ldstr指令的格式如下所示:

     

    ldstr <parameter string>

    我们可以用ILAsm.exe来编译这个程序。在运行ILAsm.exe之前,首先需要确认一下该程序已经包含在了Windows操作系统的Path环境变量中。ILAsm.exe 可在下面的路径中找到:

     

    %windir%/Microsoft.NET/Framework/v1.0.xxxx

    其中xxxx是正在使用的.NET框架的内部版本号。例如我使用的版本号是3705,则应该如下设置Path环境变量:

     

    Set Path = %Path%;c:/Windows/Microsoft.NET/Framework/v1.0.3705

    然后运行cmd.exe(开始->运行->输入cmd->按下确认键)。在弹出的命令窗口中输入:

     

    J:/Testcode>ilasm HelloWorld.il

    汇编代码后运行程序就可以看到Hello World.的输出。

    通过上面的例子,我们了解了中间语言的程序结构,一些命令和指令。同时需要提醒大家的是中间语言是区分大小写的。

    2.改进的HelloWorld例子

    在.Net中的所有语言都是面向对象的语言,但是上面的HelloWorld例子是一个结构化的例子。下面让我们来看一下如何将它转化为面向对象的代码。在面向对象的编程中,我们将操作定义在类中。为了将上面的HelloWorld例子转化为面向对象的代码,可以使用class命令:

     

    .class HelloWorld { }

    class命令后紧跟的是类的名称。类的名称在中间语言中是可选的。同时我们还需要为该指令添加一些属性,例如存取控制类在内存中的布局和互用性等。这样代码就变成了:

     

    .assembly HelloWorldIL {} .class public auto ansi HelloWorld extends [mscorlib]System.Object { .method public hidebysig static void HelloWorld() cil managed { .entrypoint ldstr "Hello World." call void [mscorlib]System.Console::WriteLine(class System.String) ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } }

    在代码中用到了三个属性:

    · public:public是访问控制属性,它表明了对于访问该类的成员没有限制。

    · auto:auto属性表明了当类被加载到内存中时,在内存中的布局是由公共运行库而不是程序决定的。

    · ansi:指定ansi属性是为了在没有被管理和被管理的代码之间实现无缝的转化。在.Net中,那些不可直接应用在公共语言基础设施之上的代码被称为没有被管理的代码,例如C、C++和VB6的代码。我们需要一个属性来处理被管理的代码和没有被管理的代码之间的互用性。在被管理的代码中,字符串用双字节的Unicode字符表示,而在被管理的代码中,字符串有可能用单字节的ANSI字符表示。指定了ansi属性就可以在不同的代码间转化字符串了。

    我们知道在.Net框架中,所有的类都直接或间接地继承了System.Object类。在代码中我们明确指定了HelloWorld继承了System.Object。

    在HelloWorld方法中加入了public、hidebysig、cil managed属性,下面是对这些属性的解释:

    · public:在C#或VB.Net中,当我们定义一个方法时,需要指定方法的访问修饰符。访问修饰符可以是public、protected、internal或private 。

    · hidebysig:一个类可以继承其他的类,hidebysig属性保证当前类中的方法在作为父类时不会被子类继承。例如如果HelloWorldChild类继承了HelloWorld类,在HelloWorldChild中不会看到HelloWorld方法。

    · cil managed:该属性将在后面讨论。

    在高级语言中(C#,VB.Net等),每个类必须有构造函数,而且构造函数的第一行需要调用基类的构造函数。如果类中没有构造函数,基类的构造函数将被自动调用。通常这是由编译器自动完成的,现在我们要在的代码中加入构造函数,该构造函数通过.ctor命令调用基类的构造函数。

     

    小结

    本文我们从经典的Hello World例子开始,通过实例了解了微软中间语言的基本语法规则以及中间语言与其他开发语言的关系。在下一篇文章中,我们将在此基础上,运用实例程序讲述.net应用程序的格式和结构等内容。

    展开全文
  • 本书全面讲述了现代编译器各个组成部分,包括词法分析、语法分析、抽象语法、语义检查、中间代码表示、指令选择、数据流分析、寄存器分配以及运行时系统等。全书分成两部分,第部分是编译的基础知识,适用于第...
  • 1.30如何判断哪些标识符可以使用,哪些被保留了? 初始化  1.31 对于没有显式初始化变量初始值可以作怎样假定?如果个全局变量初始值为“零”,它可否作为空指针或浮点零?  1.32 下面的代码为什么不能...
  • 10.求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m [Page] 答: int Num = this.TextBox1.Text.ToString() ; int Sum = 0 ; for (int i = 0 ; i ; i++) { if((i%2) == 1) { Sum += i ; ...
  • ASP.NET精品课程+源代码

    千次下载 热门讨论 2009-01-05 20:15:51
    对高职教育进行准确定位,明确高职教育是突出实践性的一种就业教育的,它所培养的是具有较高水平、较高素质高技能型人才。因此,按照“以职业活动为导向,突出职业能力目标的培养;以项目为载体,用任务训练学生的...
  • GPL 是一种可以使你免费获得自由软件许可证,因此 Linux 使用的使用活动基本不受限制(只要你不将它用于商业目的),而不必像使用微软产品是那样, 2需要为购满许可证付出高价还要受到系统安装数量限制。我...
  • 从1996年开始使用Oracle,在应用开发、大型系统实现以及性能评估方面具有丰富经验。她是OakTable成员,同时是Expert Oracle Practices (2010年 Apress出版)合著者。  RIYAJ SHAMSUDEEN 专注于性能/...
  • iPhone开发秘籍(第2版)--源代码

    热门讨论 2012-12-11 13:51:22
     《iphone开发秘籍(第2版)》提供了关于iphone sdk以及iphone开发全面信息,对iphone sdk中的各种组件做了深入浅出介绍,包括iphone 3.0 sdk所有新增特性,同时对iphone开发基本流程、基本原理和基本原则...
  • ④ 模板设置文件名称为“template.ini”,如果和主程序同一路径,可以使用相对路径 罗嗦了点,不过管用 要自动创建带有某种后缀文件,方法同上。 【9】软件技巧——提示找不到语法文件 *.stx 解决办法 原因多为...
  • ASP.NET在线测评系统

    热门讨论 2009-12-25 22:26:50
    其中,WEB服务为程序使用SOAP在Internet上通信提供了一种机制,这也是未来网络信息处理的一个主要方向。 综观.net体系,它在软件项目开发具有以下一些值得关注的优点。 1) 语言集成。可以使程序人员真正实现跨...
  • 二十三设计模式【PDF版】

    热门讨论 2011-05-30 14:13:49
    因此,你会在许多面向对象系统中看到类和相互通信对象( c o m m u n i c a t i n go b j e c t)重复模式。这些模式解决特定设计问题,使面向对象设计更灵活、优雅,最终复用性更 好。它们帮助设计者将新...
  • 通过学习书中的代码和图例,您不仅能访问和修改数据库信息,编写功能强大pl/sql语句,执行有效查询和部署稳固安全性,还能轻松实现c、c++和java过程,建立可启用web数据库,缩短开发时间和优化性能。...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    18.2 在 C #代码中调用 C++和 VB 编写组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...
  • 你必须知道495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    1.30如何判断哪些标识符可以使用,哪些被保留了? 初始化 1.31 对于没有显式初始化变量初始值可以作怎样假定?如果个全局变量初始值为“零”,它可否作为空指针或浮点零? 1.32 下面的代码为什么不能...
  • C#微软培训资料

    2014-01-22 14:10:17
    <<page 1>> page begin==================== 目 目目 目 录 录录 ... 2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得纪念的一天 这一天 微软公司正式推出了其下一代...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 192
精华内容 76
关键字:

编译系统中可以使用的一种中间代码