看了.Net的一本书,对IL做了一些初步的了解,做个随笔。
IL是Intermediate Language简称,不管什么语言编写的.net程序最终都会被编译成IL指令,并再将其动态编译成本地CPU执行的机器指令再执行。但是IL代码一般以二进制方式存在,不便阅读,当然如果愿意,也可以用任意一个Notebook直接编写IL汇编源代码,然后使用ilasm.exe程序编译成IL指令。CLR只能执行二进制的IL指令。
IL的最初设计者是乔纳森.弗博斯,98年时开发了IL编译器和反编译器的最初版本,99年时Serger Lidin(牛人)加入IL开发团队,将IL编译器和反编译器成熟起来,IL语言才开始在业界得到应用。为了让此技术得到更多的推广,Serger编写了:Inside Microsoft.Net IL Assembler,在2002年出版,后来又升级到2.0,此书为目前有关IL的最权威技术书籍,但是由于这哥们不是一个优秀的作者,导致该书非常不易读,翻译成中文就更加难以理解,所以不甚流行。
那么为什么要学习IL呢?1、了解CLR的运作机理,如果想弄清楚CLR的功能,直接看IL的指令是最便捷的;2、可以更好的掌握C#等语言,就像C#中的语法糖,是否是新特性,看看IL指令就都明白了;3、从底层开始优化程序性能,如果想让程序跑的更快,那就看IL代码的执行过程,也就能够对比出运行缓慢的原因了;4、了解程序的堆栈虚拟机(CLR其实是基础堆栈的虚拟计算机,历史上曾经存在的,他是80年Robert S.Barton设计的,解决计算机递归问题,B5000除了采用堆栈式的体系结构,也是最早采用虚拟存储器技术和多道程序设计系统的计算机,只是后来被结构性计算机替代了,但是后进先出的特性却永远的被保留了下来)。
好了,说了那么多,试着编写一个IL汇编程序吧,打开notebook,输入下列代码:
.assembly extern mscorlib {}
.assembly Test
{
.ver 1:0:1:0
}
.module test.exe
.method static void main()cil managed
{
.maxstack 1
.entrypoint
ldstr "hello IL world"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
然后将文本保存为test.il文件,然后用visual studio的命令行写入:ilasm test.il,系统就会将这个文件编译成一个test.exe文件。
好了,执行即可了。有空可以试试。
再聊聊ildasm.exe的工具,这个工具可以将程序集反汇编为IL程序,这个工具在vistual studio工具下都自带了,
用它可以查看这个程序集的清单信息:
可以方便的查看所有的IL源码。
当然要想读懂IL代码还需要掌握不少专业的术语:例如:newobj就是创建对象,box是进行装箱等,要知道的是IL指令的最重要特性就是基于堆栈,几乎每条指令都与堆栈打交道(这里的堆栈是指计算堆栈 Evaluation Stack),不要和真实系统中的堆栈混为一谈。
IL汇编程序入口都是main函数,就像py也是一样,程序结构非常类似C语言,也采用函数调用的方式变成。
.entrypoint 是程序集的入口点 .maxstack 2是说最多使用两个计算堆栈槽(slot);nop 空操作;ret 返回;ldloc 将变量压入堆栈;等等,有不少常用的指令,大家可以多多了解。
好了,就先聊到这里吧。