《你必须知道的.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 ...
随机推荐
- XE3随笔15:使用 IXMLHTTPRequest 简单获取网页源代码
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...
- phantomjs和angular-seo-server实现angular单页面seo
1.下载phantomjs,并配置环境变量为 eg:E:\phantomjs-2.1.1-windows\bin 2.下载angular-seo-server 3.windows下:cmd eg: ...
- 深入研究C语言 第一篇(续)
没有读过第一篇的读者,可以点击这里,阅读深入研究C语言的第一篇. 问题一:如何打印变量的地址? 我们用取地址符&,可以取到变量的偏移地址,用DS可以取到变量的段地址. 1.全局变量: 我们看到 ...
- MATLAB寻找数组前k个大值
有时候我们需要寻找数组的前k个大值并按照顺序输出, 在C语言可以通过快速排序等算法,快速求得,这里用matlab写了一个比较简单实用的程序(适用于数组长度不是特别大的情况). function [va ...
- XAMARIN +VS2015 ANDROID 开发禁止屏幕自动转动 Portrait,Nosensor
网上有很多java的写法,但是放在C#中都无法使用,其实有时候还是安下心来认真的去看官网文档比在百度或者google来的快的多 this.RequestedOrientation = Android. ...
- Free git private repo
今天在网上搜索了一下,发现除了github之外还有很多免费的git server,列表可以见 https://git.wiki.kernel.org/index.php/GitHosting 对比了一 ...
- <form>属性
当form表单中action没有值时,默认当前页方法.
- zabbix server配置文件
这样的错误日志,并且在web端也没有画出图来. 解决方法: ①编辑zabbix服务器端的配置文件/etc/zabbix/zabbix_server.conf找到"Timeout"把 ...
- Microsoft.Office.Interop.Excel 程序集引用 ,Microsoft.Office.Interop.Excel.ApplicationClass 无法嵌入互操作类型
using Microsoft.Office.Interop.Excel 添加程序集引用 方法:在引用--程序集--扩展中,添加引用Microsoft.Office.Interop.Excel,此 ...
- CentOS详解top命令各个数据的含义
最近在docker(宿主机是centos虚拟机)里安装gitlab,发现随着时间的运行,虚拟机的内存持续走高,运行几个小时之后内存已经爆掉了,putty远程处理于假死状态. 这个时候就需要查看内存进程 ...