批驳小赵之IL无用论(1)

      道理越辨越明。我不是来吵架的,而是来澄清一些概念。赵劼的看法实在有些偏激,但凡与之意见向左的,一概穷追猛打至死。赵同学在社区的影响力在我之上,但这也正是其可怕之处——一旦有所偏差,必然会误导更多的朋友。有感于他的毁人不倦大多穿凿附会之说,于是,暂时搁下手上的工作,发此文以正视听。

      综观赵劼《老赵谈IL:IL是什么,它又不是什么?那么汇编呢?》一文,对我的指责主要集中在2个地方:

 

      其一:我曾经指出,UltraEdit32也可以观察IL中的一些数据,但是没有给出具体操作办法。于是赵劼就单方面理解为我是信口开河,并多次在公开场合抓住这个话柄对我进行诋毁。我其实不是很想提及这个办法,所以一直没有说破,因为这个法子太过BT。介绍如下:

      首先,我们信手写一个简单的a.cs文件: 

public class Bao
{
    
public static void Main()
    {
        System.Console.WriteLine(
"hello, Jianqiang!");
    }
}

      编译命令如下:

csc b.cs

于是生成b.exe文件。

      我们用UltraEdit32打开它,

clip_image002

      以上是第1到第9行,怎么看这个图呢?

      开始的MZ是一个魔数,用来纪念设计DOS内存管理系统的人,所有exe文件都是以这两个字母作为开始的,也就是4D和5A,你可以去查ASCII表,但是有了UltraEdit32,我们可以只看右边对应的字母。接下来是一句话:This is program cannot be run in DOS mode。这句话是一句友好的错误信息,会在运行环境不对导致推出时向用户显示。有人会问,中间那些句点和乱码是什么?不要管它,有的时候右边的信息会给我们误导,因为有时我们要一次读2个字节,我们只按照微软文档的offset和size找出那些位于固定位置的信息就可以了。比如说,接下来是PE头的全部所有信息,比如说PE 头的魔数00(第80h行开始4个字节 50 45 00 00, 即PE00),只要按照偏移量和大小来找,都可以找到。

      继续找下去,还能发现更多数据:比如说第80h行的4C 01,表示Machine 0x014C,而之后的03 00则表示有3个Section,等等。

      看到这里,你也许会觉得很累,没错,我也很累,但是为了证明用UltraEdit32也能看IL中的数据,我只好半夜不睡觉眯着眼睛找这些东西,让某些人心服口服外带佩服。对于PE头,这法子百试百灵。这时候,某些人又会吹毛求屁了,说你有本事找个元数据给我看看啊?注意,我没有说过从UltraEdit32可以看到IL的所有数据,尤其是那些放在#~流中的压缩数据。但是,我另有办法,这法子是一位印度哥哥教我的,就是用C#中的IO操作来读取exe文件,只要按照微软文档定义的规格来做就可以:

      还是刚才那个a.exe文件,编写如下代码:

Code

(以上代码部分参考自Vijay Mukhi的Metadata Tables一书,稍有修改并加以中文注释)

      这里我只显示类的名称Bao,以及相应的Flags,如下图所示:

clip_image004

      再往下写就能写出一个包版的ILDASM了。

      老实说,如果不是今天和赵同学吐口水,我吃饱了没事干也不会用UltraEdit32和C#干这个事情。花了大半夜在写这些东西,还是值得的。只是想教育某些人,尤其是牛人,不要总自以为是,认为凡是与你观点不同的就一定是错误的。

 

      其二,赵劼认为我分不清IL和汇编,于是语重心长的摘抄了大段大段的定义来指导我什么是IL,什么又是汇编。选择只有两种,要么不接受,那就是冒天下之大不韪,公然和“教科书”叫板;要么接受,这些定义确实是对的,但就变成了你赵劼对我的教诲和指责也是对的,我也要接受。

      我只好耸耸肩以示无奈——用不着你来教我,这些概念我也知道。

      IL Assembler究竟是什么?我这里也有一则定义,来自微软MS IL Team,相信要比你用来引经论典的《Essential .NET》和《CLR via C#》更加权威吧:

      Unlike high-level languages, and like other assembly languages, ILAsm is platform-driven rather than concept-driven. An assembly language usually is an exact linguistic mapping of the underlying platform, which in this case is the common language runtime.

      就是说,“ILAsm不同于高级语言而类似于其他汇编语言,它是平台驱动而非概念驱动的。一门汇编语言通常会与底层平台之间存在精确的语言映射,在目前的情况下,这个底层平台就是CLR”。

      我很奇怪,微软既然用的是IL Assembler而不是IL Complier,就已经表明要把它当作一门汇编语言了,但是,为什么又有人跳出来加上“面向对象的”、“高级的”这样的定语以示区别呢?猪就是猪,哪怕它能跳起来像你我一样写代码,也还是猪。更何况连设计者都认同了,可使用者还坚持所谓的“白马非马”之说,这就滑天下之大稽了。

     

      话说,我最不该做的,就是对赵劼认为“不该学习IL”的观点第一个产生异议。老虎的屁股摸不得,于是新仇旧账一起算,列数了我以上若干罪名。不过呢,我也有和赵同学一样的嗜好,就是抓住一点坚决不放手,直到你认罪伏法。

      是否要学习一点IL呢,这取决于程序员的修为以及领域。我早在《Expert .NET 2.0 IL Assembler 译者序》中明确指出,对于2-3年编程经验的程序员,学这门技术无异于玩火自焚;5年左右经验也未必,因为你可能习惯了企业级编程,对这些底层的东西难以接受。但是,要看懂赵劼的文章《从汇编入手,探究泛型的性能问题》,没有IL这方面的修为是绝对不行的。但赵同学实在不该画蛇添足,在文章末尾散布“不该学习IL”的言论。这对你的追随者而言无异于画饼充饥。一面在炫耀这东西多好多好,一方面又在告诉大家不要去买,因为你买不起,只能看着我买我享受。

 

      既然赵劼再次提到了我翻译的《Expert .NET 2.0 IL Assembler》一书,我也只好多说几句。其实我一直很感激赵同学,因为他从我翻译伊始就泼冷水,说我会毁了这本书。其实,这种人心肠不坏,只是有一张臭嘴;不过,这反而到激发了我对这本书的精益求精——我还就阿Q了。谢谢,谢谢!

      还有就是,没事别总拿MVP当噱头,赵劼同学你在挖苦我的同时,也请注意一下自身形象,想想这样做对己对人的不良影响。

posted @ 2009-06-02 04:48 包建强 Views(...) Comments(...) Edit 收藏