Microsoft Visual Studio® .NET 提供了一个称作 ILDASM 的工具,用于列出封装在程序集中的类型信息。请参考:
//这是个使用示例
http://www.microsoft.com/china/msdn/library/dnexcl2k2/html/odc_offcs.asp
//MS官方发布的
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconmsildisassemblerildasmexe.asp
//其他
wlbookwl.myrice.com/jck/1026net.htm
www.vckbase.com/vckbase/vckbase10/ vc/nonctrls/dotnet_36/1036002.htmGOOD LUCK TO YOU

解决方案 »

  1.   

    本教程介绍 .NET 框架 SDK 随带的 MSIL 反汇编程序 (Ildasm.exe)。Ildasm.exe 可对任意 .NET 框架 .exe 或 .dll 程序集进行分析,并以可读的格式显示信息。Ildasm.exe 不只是显示 Microsoft 中间语言 (MSIL) 代码,它还显示命名空间和类型,包括其接口。您可以使用 Ildasm.exe 来检查诸如 Mscorlib.dll等的本机 .NET 框架程序集以及第三方提供的或您自己创建的 .NET 框架程序集。大多数 .NET 框架开发人员将发现 Ildasm.exe 是不可缺少的。要学习此教程,请使用 SDK 附带的 WordCount 示例的 C# 版本。您也可以使用 VB 版本,但是,对于两种语言,生成的 MSIL 将各不相同,并且屏幕图像也将有差异。WordCount 位于 FrameworkSDK\Samples\Applications\WordCount 目录中。要生成并运行此示例,请按照 Readme.htm 文件所述的说明操作。本教程使用 Ildasm.exe 来检查 WordCount.exe 程序集。若要开始,请生成 WordCount 示例并使用下列命令行将其加载到 Ildasm.exe:ildasm WordCount.exe这样将出现 Ildasm.exe 窗口,如下图所示。Ildasm.exe 窗口中的树显示了 WordCount.exe 中包含的程序集清单信息和四个全局类类型:App、ArgParser、WordCountArgParser 和 WordCounter。 双击树中的任何类型,可查看有关该类型的详细信息。在下图中,WordCounter 类类型已经展开。在上图中,您可以看到所有 WordCounter 成员。下表介绍各个图形符号的含义。符号 含义 
     更多信息 
     命名空间 
     类 
     接口 
     值类 
     枚举 
     方法 
     静态方法 
     字段 
     静态字段 
     事件 
     属性 
     清单或类信息项 双击 .class public auto ansi beforefieldinit 项可显示以下信息:在上图中,可以很容易地看出 WordCounter 类型是从 System.Object 类型中派生的。WordCounter$WordOccurrence 项表示嵌套类型。即,WordCounter 类型包含被称为 WordOccurrence 的另一类型。您可以展开 WordOccurrence 类型来查看其成员,如下图所示。查看此树,您可以看到 WordOccurrence 实现 System.IComparable 接口,尤其是 CompareTo 方法。但是,此对话的其余部分将忽略 WordOccurrence 类型,而改为集中于 WordCounter 类型。您可以看到 WordCounter 类型包含五个 private 字段:totalBytes、totalChars、totalLines、totalWords 和 wordCounter。这些字段中的前四个是 int64 类型的实例,而 wordCounter 字段是对 System.Collections.SortedList 类型的引用。循着字段,您可以看到方法。第一种方法 .ctor 是一个构造函数。此特定类型只有一个构造函数,但其他类型可以有几个构造函数,每个构造函数都带有不同的签名。WordCounter 构造函数有返回类型 void(所有构造函数均是如此)且不接受参数。如果您双击该构造函数方法,将出现一个新窗口,其中显示此方法中包含的 MSIL 代码,如下图所示。MSIL 代码实际上易读易懂。(有关所有详细信息,请参阅 CIL Instruction Set Specification(CIL 指令集规范),该规范位于 FrameworkSDK\Tool Developers Guide\Docs 文件夹下的 Partition III CIL.doc 文件中。)在顶部,您可以看到此构造函数需要 50 字节的 MSIL 代码。仅凭此数字,您实际上并不知道 JIT 编译器将发出多少本机代码,因为该大小取决于主机 CPU 以及用于生成代码的编译器。公共语言运行库以堆栈为基础。因此,为了执行运算,MSIL 代码先将操作数推至虚拟堆栈上,然后执行运算符。运算符从堆栈抽取操作数,执行所要求的运算,并将结果放回到堆栈上。此方法一次最多都只能将八个操作数推至虚拟堆栈。您可以通过查看在 MSIL 代码前面出现的 .maxstack 属性来识别此数字。现在,请查看前几条 MSIL 指令,它们在以下四行上重现:IL_0000: ldarg.0 ; Load the object's 'this' pointer on the stack
    IL_0001: ldc.i4.0 ; Load the constant 4-byte value of 0 on the stack
    IL_0002: conv.i8 ; Convert the 4-byte 0 to an 8-byte 0
    IL_0003: stfld int64 WordCounter::totalLines位于 IL_0000 的指令将传递至此方法的第一个参数加载到虚拟堆栈上。始终向每个实例方法传递对象内存的地址。此参数称为“参数零”,且从不在方法签名中明确显示。因此,虽然 .ctor 方法看起来接收零参数,但它实际却接收一个参数。然后,位于 IL_0000 的指令将此对象的指针加载到虚拟堆栈上。IL_0001 的指令将 4 字节的常量零值加载到虚拟堆栈上。IL_0002 的指令从堆栈的顶部取值(4 字节的零),并将其转换为 8 字节的零,这样,便将 8 字节的零放在了堆栈的顶部。此时,堆栈包含两个操作数:8 字节的零和此对象的指针。IL_0003 的指令使用这两个操作数将堆栈顶部的值(8 字节的零)存储到堆栈上所识别对象的 totalLines 字段中。对于 totalChars、totalBytes 和 totalWords 字段重复相同的 MSIL 指令顺序。wordCounter 字段的初始化从指令 IL_0020 开始,如下所示:IL_0020: ldarg.0
    IL_0021: newobj instance void [mscorlib]System.Collections.SortedList::.ctor()
    IL_0026: stfld class [mscorlib]System.Collections.SortedList WordCounter::wordCounterIL_0020 的指令将 WordCounter 的 this 指针推至虚拟堆栈上。newobj 指令不使用此操作数,但 IL_0026 的 stfld 指令将使用此操作数。IL_0021 的指令通知运行时新建 System.Collections.SortedList 对象并且不带参数调用其构造函数。当 newobj 返回时,SortedList 对象的地址位于堆栈上。此时,IL_0026 的 stfld 指令将 SortedList 对象的指针存储到 WordCounter 对象的 wordCounter 字段中。在 WordCounter 对象的所有字段均已初始化之后,IL_002b 的指令将 this 指针推至虚拟堆栈上,并且 IL_002c 调用基类型 (System.Object) 中的构造函数。当然,IL_0031 的最后一条指令是使 WordCounter 构造函数返回创建它的代码的返回指令。构造函数需要返回 void,因此,在该构造函数返回之前,堆栈上不会放任何内容。现在请看另一示例。双击 GetWordsByOccurranceEnumerator 方法查看其 MSIL 代码,如下图所示。您会看到此方法的代码大小为 69 字节,并且此方法要求虚拟堆栈上有四个插槽。另外,此方法有三个局部变量:一个为 System.Collection.SortedList 类型,另外两个为 System.Collections.IDictionaryEnumerator 类型。请注意,源代码中提到的变量名称不发到 MSIL 代码,除非使用 /debug 选项编译程序集。如果不使用 /debug,则使用变量名称 V_0、V_1 和 V_2 分别代替 sl、de 和 CS$00000003$00000000。当此方法开始执行时,它首先要做的是执行 newobj 指令,该指令创建新的 System.Collections.SortedList 并调用此对象的默认构造函数。当 newobj 返回时,所创建对象的地址位于虚拟堆栈上。stloc.0 指令(在 IL_0005)将此值存储在局部变量 0 或 sl(无 /debug 的 V_0 )(它是 System.Collections.SortedList 类型)中。在指令 IL_0006 和 IL_0007 处,将 WordCounter 对象的 this 指针(在传递至方法的“参数零”中)加载到堆栈上,并且调用 GetWordsAlphabeticallyEnumerator 方法。当 call 指令返回时,枚举数的地址位于堆栈上。stloc.1 指令(位于 IL_000c)将此地址保存在局部变量 1 或 System.Collections.IDictionaryEnumerator 类型的 de(无 /debug 的 V_1)中。IL_000d 的 br.s 指令使 while 语句的 IL 测试条件产生一个无条件分支。此 IL 测试条件开始于指令 IL_0032。在 IL_0032 处,将 IDictionaryEnumerator 类型的 de(或 V_1)的地址推至堆栈上,并且,在 IL_0033 处,调用其 MoveNext 方法。如果 MoveNext 返回 true,则存在要枚举的项,并且 brtrue.s 指令跳至 IL_000f 处的指令。在指令 IL_000f 和 IL_0010 处,sl(或 V_0)和 de(或 V_0)中对象的地址被推至堆栈上。然后,调用 IdictionaryEnumerator 对象的 get_Value 属性方法来获取当前项出现的次数。此数字为存储在 System.Int32 中的一个 32 位值。代码会将此 Int32 对象强制转换为 int 值类型。将引用类型强制转换为值类型需要 IL_0016 的 unbox 指令。当 unbox 返回时,未装箱的值的地址位于堆栈上。ldind.i4 指令(位于 IL_001b)将当前在堆栈上指向该地址的 4 字节值加载到堆栈上。换言之,未装箱的 4 字节整数放置在堆栈上。在指令 IL_001c 处,将 sl(或V_1)的值(IDictionaryEnumerator 的地址)推至堆栈上,并调用其 get_Key 属性方法。当 get_Key 返回时,System.Object 的地址位于堆栈上。代码知道词典包含字符串,因此编译器在 IL_0022 使用 castclass 指令将此 Object 强制转换为 String。下面几条指令(从 IL_0027 至 IL_002d)创建新的 WordOccurrence 对象,并将该对象的地址传递至 SortedLists 的 Add 方法。 在指令 IL_0032 处,再次计算 while 语句的测试条件。如果 MoveNext 返回 true,则循环执行另一迭代。但是,如果 MoveNext 返回 false,执行将跳出循环并在指令 IL_003a 处终止。IL_003a 至 IL_0040 的指令调用 SortLists 对象的 GetEnumerator 方法。返回的值为 System.Collections.IDictionaryEnumerator,它保留在堆栈上,成为 GetWordsByOccurrenceEnumerator 返回值。