通过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                               //版本号
     }
     .assembly MSILTest //程序集
 {
  ..//程序集模块省略
 }
    .module MSILTest.exe

 // MVID: {118CBB3B-E1A4-4453-A91E-85C22F861EDC}
 .imagebase 0x00400000
 .file alignment 0x00001000                              
   //文件对齐数值
 .stackreserve 0x00100000                               
   //文件对齐数值
 .subsystem 0x0003       // WINDOWS_CUI        
  //连接系统类型
 .corflags 0x00000001    //  ILONLY                   
   //运行库头文件标志
 // 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
   .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                                                
   //评估堆栈可容纳数据项的最大个数
    IL_0000:  ldarg.0                                          
   //装载第一个成员方法,在实例方法中代表当前实例的引用,该引用将用于基类构造中调用
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()        
   //调用基类Object的构造,call一般用于调用静态方法
    IL_0006:  ret                                                  
   //return
  } // end of method Program::.ctords
  .method                                                           
  //代表方法
  public                                                               
  //访问权限
  hidebysig                                                          
  //不能被子类继承
 
  双击Main:void(string[])  程序入口
  .method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint                                                        
  //程序入口
  // 代码大小       19 (0x13)
  .maxstack  8                                                     
  //评估堆栈可容纳数据项的最大个数
  IL_0000:  nop                                                    
  //无操作
  IL_0001:  ldstr      "hello world!"                          
  //ldstr即load sting,将字符串压入栈,字符串被移到stack顶部
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  //调用Console类的WriteLine方法
  IL_000b:  nop
  IL_000c:  call       string [mscorlib]System.Console::ReadLine()              
  IL_0011:  pop
  IL_0012:  ret                                                      
  //return 执行完毕
} // end of method Program::Main
参考:你必须知道的.Net
            MSDN帮助文档
记得老师说过学习是死去活来的过程,不理解不要紧,慢慢了解。
 
posted @ 2010-09-10 15:29  birchlee  阅读(422)  评论(2编辑  收藏  举报