通用的语言基础是.NET运行的基础,当我们对程序运行的结果有异议的时候,如何透过本质看表面,需要我们从底层来入手探索,这时候,IL便是我们必须知道的基础。

一、IL基础概念

1.1 什么是IL?

  IL是.NET框架中间语言(Intermediate Language)的缩写。使用.NET框架提供的编译器可以直接将源程序编译为.exe或.dll文件,但此时编译出来的程序代码并不是CPU能直接执行的机器代码,而是一种中间语言IL(Intermediate Language)的代码。

1.2 为何要了解IL?

  元数据和IL是CLR的基础,了解必要的IL是深入认识CLR的捷径,我们没有理由放弃一条可以直接通达大门的便捷之路而盲目地以其他的方式追求深入。同时,大量的事例分析都是以IL来揭秘的,因此了解IL是读懂他人代码的必备基础,可以给自己更多的收获。

二、IL分析工具

2.1 ILASM.exe和ILDASM.exe

  .NET Framework中自带了一套成熟的编译于反编译利器:ILASM.exe和ILDASM.exe,其中ILASM.exe工具用来执行IL代码并生成可执行程序,而ILDASM.exe则用来反编译可执行程序(反编译为IL代码进行查看)。

2.2 Reflector.exe

  Reflector是由微软员工Lutz Roeder编写的免费程序。Reflector的出现使·NET程序员眼前豁然开朗,因为这个免费工具可以将·NET程序集中的IL反编译成C#或者Visual Basic代码。除了能将IL转换为C#或Visual Basic以外,Reflector还能够提供程序集中类及其成员的概要信息、提供查看程序集中IL的能力以及提供对第三方插件的支持。

三、一个Hello World的IL之旅

3.1 准备一个Hello World程序

using System;
using System.Data; namespace HelloIL
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

3.2 利用ILDASM体验IL

  (1)对编译后的可执行文件HelloIL.exe,使用ILDasm.exe进行反编译,将会还原HelloIL为IL编码,结构如下:

  分为两个部分:MANIFEST和HelloIL程序集。

  (2)其中,MANIFEST是附加信息列表,主要包含了程序集的一些属性:程序集名称、版本号、哈希算法、程序集模块等,以及对外部引用程序集的引用项:

// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C E0 ) // .z\V.4..
.ver :::
}
.assembly HelloIL
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 4E 6F 6E // ....T..WrapNonEx
6F 6E 6F ) // ceptionThrows.
.hash algorithm 0x00008004
.ver :::
}
.module HelloIL.exe
// MVID: {C176F7F5-9415-4616-A709-E08967A0C6A0}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00000000003C0000

  ① .assembly指令用于定义编译目标或者加载外部库:这里只加载了mscorlib核心库,而System.Data被忽略,有效避免了过度加载引起的代码膨胀;

  ② .ctor指令表示构造函数,代码里没有任何显示构造函数,因此这里调用基类System.Object的构造函数(System.Object位于mscorlib程序集中);

  (3)其次,HelloIL程序集是我们要分析的重点:

  ① 首先是Program类

  ② 然后是ctor方法(构造方法)

  ③ 最后是Main方法

  (4)化繁为简,一览天下

  这里将上面的IL代码简化一下,去粗取精来展现一下上面示例的IL代码,详细的分析以注释方式描述:

    // 加载外部程序集
.assembly extern mscorlib
// 指定编译目标程序集
.assembly HelloIL .class Program extends [mscorlib]System.Object
{
.method public instanct void .ctor() cil managed
{
.maxstack
// 调用基类构造函数
ldarg.
call instance void [mscorlib]System.Object::.ctor()
// 执行完毕,返回
ret
} .method static void Main() cil managed
{
// 表明程序入口点
.entrypoint
.maxstack
// 装载string对象
ldstr "Hello World!"
// 调用静态方法WriteLine
call void [mscorlib]System.Console::WriteLine(string)
// 执行完毕,返回
ret
}
}

3.3 IL体验小结

  通过一个Hello World示例,我们和IL进行了第一次的亲密接触。认识IL,是个循序渐进的过程,有了本次的小示例作为铺垫,我们可以轻松地认识简单的IL代码了。

参考资料

(1)本文源自王涛(anytao)的《你必须知道的.NET(第二版)》,感谢金馆长熊猫表情。

(2)Zery,《读懂IL就这么简单(一)

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

《你必须知道的.NET》读书笔记:从Hello World认识IL的更多相关文章

  1. 你必须知道的.net读书笔记之第二回深入浅出关键字---对抽象编程:接口和抽象类

    请记住,面向对象思想的一个最重要的原则就是:面向接口编程. 借助接口和抽象类,23个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程. 抽象类应主要用于关系密切的对象,而接口 ...

  2. 你必须知道的.net读书笔记第四回:后来居上:class和struct

     基本概念 1.1. 什么是class? class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段.属性.方法.属性.构造函数.索引器.操作符等.因为是基本的概念,所以不必在此 ...

  3. 必须知道的.net——学习笔记1

    1.对象的生成(出生) Person aperson=new Person("小张",25) 构造过程:分配存储空间—初始化附加成员—调用构造函数 2.对象的旅程(在一定的约定与规 ...

  4. [你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理

    原文地址:http://kb.cnblogs.com/page/42318/ 系列文章导航: [你必须知道的.NET] 开篇有益 [你必须知道的.NET] 第一回:恩怨情仇:is和as [你必须知道的 ...

  5. [你必须知道的.NET]第二十四回:认识元数据和IL(上)

    发布日期:2009.02.24 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 很早就有说说Metadata(元数据)和IL(中 ...

  6. [你必须知道的.NET]第二十六回:认识元数据和IL(下)

    发布日期:2009.03.04 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回: 第二十四回:认识元数据和IL(上), ...

  7. [你必须知道的.NET]第二十五回:认识元数据和IL(中)

    发布日期:2009.02.25 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回[第二十四回:认识元数据和IL(上)], ...

  8. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  9. 《你必须知道的.NET》读书笔记一:小OO有大智慧

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.对象  (1)出生:系统首先会在内存中分配一定的存储空间,然后初始化其附加成员,调用构造函数执行初 ...

  10. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

随机推荐

  1. Ceph剖析:故障检测

    作者:吴香伟 发表于 2014/10/10 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 心跳是用于OSD节点间检测对方是否故障的,以便及时发现故障节点进入相应 ...

  2. spring aop实现

    Spring 有如下两种选择来定义切入点和增强处理. 基于 Annotation 的"零配置"方式:使用@Aspect.@Pointcut等 Annotation 来标注切入点和增 ...

  3. 云端卫士实战录 | Java高级特性之多线程

    <实战录>导语 一转眼作为一名Java开发者已经四年多时间了,说长不长说短不短,对于java的感情还是比较深的,主要嘛毕竟它给了我饭吃.哈哈,开个玩笑.今天我想借此机会来和大家聊聊Java ...

  4. HTML5新增的属性

    关于html5新增的属性: HTML5现在已经不是SGML的子集,主要是增加了关于图像,位置,存储,多任务等功能. 绘画CANVAS; 用于播放媒体的video和audio元素: 本地离线存储loca ...

  5. JSP知识

    五.JSP概述及最佳实践1.更改MyEclipse生成的JSP模板.模板文件与Servlet.java(Servlet模板文件)很近.2.学好JSP的关键:JSP就是Servlet.一定要记住JSP中 ...

  6. Excel导入-----导出(包含所选和全部)操作

    在做系统的时候,很多时候信息量太大,这时候就需要进行Excel表格信息的导入和导出,今天就来给大家说一下我使用Excel表格信息导入和导出的心得. 1:首先需要在前端显示界面View视图中添加导入Ex ...

  7. MySQL提示符含义

    http://www.splaybow.com/post/mysql-prompt-introduce.html mysql> 准备好接受新命令. 说明:正常等待输入的提示符. -> 等待 ...

  8. Max Sum

    Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub ...

  9. 解析 Json 相关

    statusJson sj = new statusJson() { ShipmentNum = "555555", Status1 = "05", Wareh ...

  10. PHP对象转数组||PHP数组转对象

    function arrayToObject($e){     if( gettype($e)!='array' ) return;     foreach($e as $k=>$v){     ...