《你必须知道的.NET》读书笔记:从Hello World认识IL
通用的语言基础是.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就这么简单(一)》
《你必须知道的.NET》读书笔记:从Hello World认识IL的更多相关文章
- 你必须知道的.net读书笔记之第二回深入浅出关键字---对抽象编程:接口和抽象类
请记住,面向对象思想的一个最重要的原则就是:面向接口编程. 借助接口和抽象类,23个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程. 抽象类应主要用于关系密切的对象,而接口 ...
- 你必须知道的.net读书笔记第四回:后来居上:class和struct
基本概念 1.1. 什么是class? class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段.属性.方法.属性.构造函数.索引器.操作符等.因为是基本的概念,所以不必在此 ...
- 必须知道的.net——学习笔记1
1.对象的生成(出生) Person aperson=new Person("小张",25) 构造过程:分配存储空间—初始化附加成员—调用构造函数 2.对象的旅程(在一定的约定与规 ...
- [你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理
原文地址:http://kb.cnblogs.com/page/42318/ 系列文章导航: [你必须知道的.NET] 开篇有益 [你必须知道的.NET] 第一回:恩怨情仇:is和as [你必须知道的 ...
- [你必须知道的.NET]第二十四回:认识元数据和IL(上)
发布日期:2009.02.24 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 很早就有说说Metadata(元数据)和IL(中 ...
- [你必须知道的.NET]第二十六回:认识元数据和IL(下)
发布日期:2009.03.04 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回: 第二十四回:认识元数据和IL(上), ...
- [你必须知道的.NET]第二十五回:认识元数据和IL(中)
发布日期:2009.02.25 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回[第二十四回:认识元数据和IL(上)], ...
- C#刨根究底:《你必须知道的.NET》读书笔记系列
一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...
- 《你必须知道的.NET》读书笔记一:小OO有大智慧
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.对象 (1)出生:系统首先会在内存中分配一定的存储空间,然后初始化其附加成员,调用构造函数执行初 ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
随机推荐
- oracle数据库升级记(记一次10.2.0.3版本升级到11.2.0.1版本的过程)
操作系统:windows xp 已有数据库版本:10.2.0.3 升级目标版本:11.2.0.1 步骤大纲: 在源操作系统(安装有10.2.0.3数据库的操作系统)上安装11.2.0.1数据库软件,然 ...
- 为什么不能访问django自带的索引页
通过HTTP://192.168.160.128:8000访问虚拟机上的django索引页出现“ 无法访问此网站 192.168.160.128 拒绝了我们的连接请求. ” 是什么原因呢?费了好大一番 ...
- jdk1.8下载安装
jdk8环境变量 jdk8图解安装 java8安装 1 2 3 4 5 6 7 分步阅读 JDK8 是JDK的最新版本,加入了很多新特性,如果我们要使用,需要下载安装: JDK8在windows ...
- C# 模拟上传图片
上传图片的格式一定要按规定的写,不然没办法正确上传的. 我在上传的时候就是值前面没有空一行,导致上传不成功,很纠结的错误. 我要模拟的是一个FLASH的上传控件,我开始用HttpAnalyze抓包是抓 ...
- 读书笔记——body and html
在看<常见标签的默认属性值及相互作用——关于CSS reset的思考>的时候,其中说body默认的margin是8px.但是,将body的backgound-color:red:后,看到的 ...
- jquery选择器使用说明
在jquery中选择器是一个非常重要的东西,几乎做什么都离不开它,下面我总结了jquery几种选择器的用法.以方便后面直接可以用到!! 层次选择器: 1.find()://找到该元素的子元素以及孙子元 ...
- Echarts给柱状图每一条顶部都添加数值
在 series中添加 itemStyle : { normal: {label : {show: true}}}, 不过目测要把markPoint等去掉,不然最大值和最小值会和label冲突,应该有 ...
- IP地址框
//IP地址框 // 此段代码:独立的获取本机IP地址和计算机名 WORD wVersionRequested; WSADATA wsaData; char name[255]; CString ip ...
- Redis多机常用架构-sentinel
哨兵经典架构 sentinel结构 哨兵工作原理 Sentinel 通过配置文件发现Master,如下: Sentinel 通过向Master发送 INFO 命令来自动获得所有Slave的地址 跟Ma ...
- Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6
书接上文,昨天装了MinGW,主要原因之一是要用到MSYS,所以顺手把FFMPEG又编译了一遍. 回到主题,其实我是想编译矢量库,因为最近要学习一些计算几何算法,所以找个方便的2D画图库就很重要. 说 ...