[Programming IL]创建一个类,How To Declare A Class

引言

在.Net平台中,面向对象是一个非常重要的概念,那么在IL是怎样对面向对象进行支持的呢?  让我们从创建一个类开始

例子

   1: .assembly extern mscorlib {}
   2: .assembly MyClass {}
   3: .class public auto unicode XWang extends [mscorlib]System.Object
   4: {    
   5:     .method public hidebysig specialname rtspecialname instance void .ctor() il managed    
   6:     {        
   7:         call instance void [mscorlib]System.Object::.ctor()        
   8:         ret    
   9:     }        
  10:  
  11:     .method public hidebysig static void main() cil managed    
  12:     {        
  13:         .entrypoint        
  14:         ldstr "Welcome to Intermediate Language"        
  15:         call void [mscorlib]System.Console::WriteLine(class System.String)        
  16:         ret    
  17:     }
  18: }

该程序从创建一个类开始,使用了构造函数并输出了一行字符串

有几个指令需要说明一下

.class 声明一个类

.method 声明方法

specialname 对于方法的特殊处理, 比如声明一个属性编译成IL也会有specialname标识

rtspecialname: 一个只用于.Net内部的标识,使用于四种情况

1. 实例构造函数 2. 类构造函数 3. _VtblGap* 声明方法表 4. _Deleted 声明不使用但是没有从元数据中删除的方法

来个复杂点的. :)

从C#开始

   1: using System;
   2: using System.Collections.Generic;
   3:  
   4: namespace Roger.Testing
   5: {
   6:     public class Testing
   7:     {    
   8:         private int m_private;
   9:         private int m_init = 2;
  10:         
  11:         public static void Main()
  12:         {
  13:         }
  14:         
  15:         static Testing()
  16:         {
  17:             // DO Something
  18:             int i = 2;
  19:         }
  20:         
  21:         public void DoSth()
  22:         {
  23:             for(int i =0; i< m_init; i++)
  24:             {
  25:                 m_private += i; 
  26:                 if(m_private > 1) m_private = 1;
  27:             }
  28:         }
  29:         
  30:         public void While()
  31:         {
  32:             while(m_init > 0) m_init--;
  33:             
  34:             do
  35:             {
  36:                 m_init++;
  37:             }while(m_init < 10);
  38:         }
  39:         
  40:         public void TestSwitch()
  41:         {
  42:             switch(m_init)
  43:             {
  44:                 case 0:
  45:                     m_private = 1;
  46:                     break;
  47:                 case 1:
  48:                     m_private = 2;
  49:                     break;
  50:                 case 2:
  51:                     m_private = 3;
  52:                     break;
  53:                 default:
  54:                     m_private = 100;
  55:                     break;
  56:             }
  57:         }
  58:     }
  59: }

那一个类的字段是如何定义的,方法是如何声明,流程如何控制的呢,我们从代码编译生成的方法列表图上面开始吧

image

1. 字段的声明

.field private int32 m_init

2. 字段的初始化

   1: .method public hidebysig specialname rtspecialname 
   2:         instance void  .ctor() cil managed
   3: {
   4:   // Code size       14 (0xe)
   5:   .maxstack  8
   6:   IL_0000:  ldarg.0
   7:   IL_0001:  ldc.i4.2
   8:   IL_0002:  stfld      int32 Roger.Testing.Testing::m_init
   9:   IL_0007:  ldarg.0
  10:   IL_0008:  call       instance void [mscorlib]System.Object::.ctor()
  11:   IL_000d:  ret
  12: } // end of method Testing::.ctor
  13:  

IL会为该类生成一个实例构造函数而后调用Object的构造函数并初始化那些数据

3. 类构造函数

method .cctor

4. IF - ELSE 判断, For循环

   1: .method public hidebysig instance void  DoSth() cil managed
   2: {
   3:   // Code size       48 (0x30)
   4:   .maxstack  3
   5:   .locals init (int32 V_0)
   6:   IL_0000:  ldc.i4.0
   7:   IL_0001:  stloc.0
   8:   IL_0002:  br.s       IL_0026
   9:   IL_0004:  ldarg.0
  10:   IL_0005:  dup
  11:   IL_0006:  ldfld      int32 Roger.Testing.Testing::m_private
  12:   IL_000b:  ldloc.0
  13:   IL_000c:  add
  14:   IL_000d:  stfld      int32 Roger.Testing.Testing::m_private
  15:   IL_0012:  ldarg.0
  16:   IL_0013:  ldfld      int32 Roger.Testing.Testing::m_private
  17:   IL_0018:  ldc.i4.1
  18:   IL_0019:  ble.s      IL_0022
  19:   IL_001b:  ldarg.0
  20:   IL_001c:  ldc.i4.1
  21:   IL_001d:  stfld      int32 Roger.Testing.Testing::m_private
  22:   IL_0022:  ldloc.0
  23:   IL_0023:  ldc.i4.1
  24:   IL_0024:  add
  25:   IL_0025:  stloc.0
  26:   IL_0026:  ldloc.0
  27:   IL_0027:  ldarg.0
  28:   IL_0028:  ldfld      int32 Roger.Testing.Testing::m_init
  29:   IL_002d:  blt.s      IL_0004
  30:   IL_002f:  ret
  31: } // end of method Testing::DoSth
  32:  

ldc.i4 加载int4(32)

br.s = br + s, br 为branch意值分支, s为short parameter

dup = duplicate, 拷贝栈顶的数据值,如果没有栈顶,则会抛出异常

ldfld = load field 加载某个字段的值

stfld = save field 保存字段的值

ble = branch if less or equal, 小于等于的分支

ble.s = short parameter的ble

blt = branch if less

5. While, Do-While

   1: .method public hidebysig instance void  While() cil managed
   2: {
   3:   // Code size       50 (0x32)
   4:   .maxstack  8
   5:   IL_0000:  br.s       IL_0010
   6:   IL_0002:  ldarg.0
   7:   IL_0003:  dup
   8:   IL_0004:  ldfld      int32 Roger.Testing.Testing::m_init
   9:   IL_0009:  ldc.i4.1
  10:   IL_000a:  sub
  11:   IL_000b:  stfld      int32 Roger.Testing.Testing::m_init
  12:   IL_0010:  ldarg.0
  13:   IL_0011:  ldfld      int32 Roger.Testing.Testing::m_init
  14:   IL_0016:  ldc.i4.0
  15:   IL_0017:  bgt.s      IL_0002
  16:   IL_0019:  ldarg.0
  17:   IL_001a:  dup
  18:   IL_001b:  ldfld      int32 Roger.Testing.Testing::m_init
  19:   IL_0020:  ldc.i4.1
  20:   IL_0021:  add
  21:   IL_0022:  stfld      int32 Roger.Testing.Testing::m_init
  22:   IL_0027:  ldarg.0
  23:   IL_0028:  ldfld      int32 Roger.Testing.Testing::m_init
  24:   IL_002d:  ldc.i4.s   10
  25:   IL_002f:  blt.s      IL_0019
  26:   IL_0031:  ret
  27: } // end of method Testing::While
  28:  

6. Switch

   1: .method public hidebysig instance void  TestSwitch() cil managed
   2: {
   3:   // Code size       60 (0x3c)
   4:   .maxstack  2
   5:   .locals init (int32 V_0)
   6:   IL_0000:  ldarg.0
   7:   IL_0001:  ldfld      int32 Roger.Testing.Testing::m_init
   8:   IL_0006:  stloc.0
   9:   IL_0007:  ldloc.0
  10:   IL_0008:  switch     ( 
  11:                         IL_001b,
  12:                         IL_0023,
  13:                         IL_002b)
  14:   IL_0019:  br.s       IL_0033
  15:   IL_001b:  ldarg.0
  16:   IL_001c:  ldc.i4.1
  17:   IL_001d:  stfld      int32 Roger.Testing.Testing::m_private
  18:   IL_0022:  ret
  19:   IL_0023:  ldarg.0
  20:   IL_0024:  ldc.i4.2
  21:   IL_0025:  stfld      int32 Roger.Testing.Testing::m_private
  22:   IL_002a:  ret
  23:   IL_002b:  ldarg.0
  24:   IL_002c:  ldc.i4.3
  25:   IL_002d:  stfld      int32 Roger.Testing.Testing::m_private
  26:   IL_0032:  ret
  27:   IL_0033:  ldarg.0
  28:   IL_0034:  ldc.i4.s   100
  29:   IL_0036:  stfld      int32 Roger.Testing.Testing::m_private
  30:   IL_003b:  ret
  31: } // end of method Testing::TestSwitch
  32:  

While 和 Do-While 和Switch都用到了Label的特性,利用Label进行跳转

 

参考:

C# To IL

Expert .Net 2.0 Assembler

posted on 2008-09-19 00:08 xwang 阅读(...) 评论(...) 编辑 收藏

导航

统计