通过MSIL看世界系列一:进入MSIL的世界
MSIL是什么呢?
先看微软官方给出的c#程序运行过程
从上图可以看出,MSIL是介于c#源文件和计算机代码的一中中间过渡语言。
.Net平台MSIL编译工具(Ilasm.exe)和反编译工具(Ildasm.exe)。
我们今天来了解一下反编译工具:
我们新建控制台应用程序 MSILTest 并编写如下代码:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hello world!");
Console.ReadLine();
}
}
执行输出Hello world
下来我们进行反编译: 开始→所有程序→Microsoft Visual Studio 2005→Visual Studio Tools→Visual Studio 2005命令提示
输入命令 ildasm E:\MSILTest\MSILTest\bin\Debug\MSILTest.exe
命令 ildasm代表反编译,E:\MSILTest\MSILTest\bin\Debug\MSILTest.exe是控制台程编译后生成的exe
(也可以 开始→所有程序→Microsoft .Net FrameWork SDK v2.0→Tools→MSIL反编译程序,然后选择MSILTest.exe)
要看懂先来了解每个图标代表的意思,参考微软官方IL树
可以查看更多
命名空间
类
方法
静态方法
双击MANIFEST,得到一下代码
.assembly extern mscrolib //加载引用程序
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. //公钥
.ver 2:0:0:0 //版本号
}
.ver 2:0:0:0 //版本号
}
.assembly MSILTest //程序集
{
..//程序集模块省略
}
.module MSILTest.exe
// MVID: {118CBB3B-E1A4-4453-A91E-85C22F861EDC}
.imagebase 0x00400000
.file alignment 0x00001000
//文件对齐数值
.stackreserve 0x00100000
.stackreserve 0x00100000
//文件对齐数值
.subsystem 0x0003 // WINDOWS_CUI
.subsystem 0x0003 // WINDOWS_CUI
//连接系统类型
.corflags 0x00000001 // ILONLY
.corflags 0x00000001 // ILONLY
//运行库头文件标志
// Image base: 0x03A50000
// Image base: 0x03A50000
//影像基地址
MAINFEST主要包含程序集的属性如:程序集名称,版本号,哈希算法,程序集模块等
双击.class private auto ansi beforefieldinit
.class private auto ansi beforefieldinit MSILTest.Program
extends [mscorlib]System.Object
{
} // end of class MSILTest.Program
extends [mscorlib]System.Object
{
} // end of class MSILTest.Program
.class
//代表是一个类
private
//代表是个私有类
auto
//代表程序加载时候内存的分配由CLR决定
ansi
//代表可以 转换成非托管代码
beforefieldinit
//系统自动调用构造,以达到优化性能的目的
MSILTest.Program
//类,继承自System.Object
双击.ctor:void() 构造函数
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed //cil managed代表托管代码
{
// 代码大小 7 (0x7)
.maxstack 8
instance void .ctor() cil managed //cil managed代表托管代码
{
// 代码大小 7 (0x7)
.maxstack 8
//评估堆栈可容纳数据项的最大个数
IL_0000: ldarg.0
IL_0000: ldarg.0
//装载第一个成员方法,在实例方法中代表当前实例的引用,该引用将用于基类构造中调用
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0001: call instance void [mscorlib]System.Object::.ctor()
//调用基类Object的构造,call一般用于调用静态方法
IL_0006: ret
IL_0006: ret
//return
} // end of method Program::.ctords
} // end of method Program::.ctords
.method
//代表方法
public
//访问权限
hidebysig
//不能被子类继承
双击Main:void(string[]) 程序入口
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
{
.entrypoint
//程序入口
// 代码大小 19 (0x13)
.maxstack 8
// 代码大小 19 (0x13)
.maxstack 8
//评估堆栈可容纳数据项的最大个数
IL_0000: nop
IL_0000: nop
//无操作
IL_0001: ldstr "hello world!"
IL_0001: ldstr "hello world!"
//ldstr即load sting,将字符串压入栈,字符串被移到stack顶部
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
//调用Console类的WriteLine方法
IL_000b: nop
IL_000c: call string [mscorlib]System.Console::ReadLine()
IL_000b: nop
IL_000c: call string [mscorlib]System.Console::ReadLine()
IL_0011: pop
IL_0012: ret
IL_0012: ret
//return 执行完毕
} // end of method Program::Main
} // end of method Program::Main
参考:你必须知道的.Net
MSDN帮助文档
记得老师说过学习是死去活来的过程,不理解不要紧,慢慢了解。