[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: }
那一个类的字段是如何定义的,方法是如何声明,流程如何控制的呢,我们从代码编译生成的方法列表图上面开始吧
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进行跳转
参考:
Expert .Net 2.0 Assembler
 
                    
                
 
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号