看懂IL代码

转载阳春三月的文章

  1//示例一:输出整数的立方值。
  2private void PrintCube( int i )
  3{
  4    int cube = i * i * i;
  5    Console.WriteLine( cube );
  6}

  7//方法签名。
  8/**//// hidebysig:MethodAttributes 枚举值之一,指示此方法按名称和签名隐藏,否则只
  9/// 按名称隐藏。
10/// cil managed:未查到具体资料,应是“受中间语言管理”之意。

11
12.method private hidebysig instance void
13          PrintCube(int32 i) cil managed
14  {
15    // 代码大小       15 (0xf)
16    .maxstack  2
17    /**//**//**//// 在 .locals 部分声明所有的局部变量。
18    .locals init ([0] int32 cube)    /**//**//**//// 第一个名局部变量,int 型,名为 cube。索
19                                    /// 引从 0 开始。

20    IL_0000:  nop    /**//**//**//// no operation.
21    IL_0001:  ldarg.1    /**//**//**//// load argument 第一个方法参数入栈,比如“3”。索引号
22                        /// 从 1 开始,而不是从 0 开始。

23    IL_0002:  ldarg.1    /**//**//**//// 再次向堆栈压入第一个方法参数,又一个“3”。
24    IL_0003:  mul    /**//**//**//// multiply 计算堆栈最顶上两个数的乘积 3×3,并把结果入栈,
25                    /// 即堆栈最顶部是 9 了。

26    IL_0004:  ldarg.1    /**//**//**//// 再次压入第一个方法参数“3”。
27    IL_0005:  mul    /**//**//**//// 堆栈最顶上是“3”,第二是“9”,计算 3×9,此时 27 入栈。
28    IL_0006:  stloc.0    /**//**//**//// pop value from stack to local variable 堆栈最顶上的
29                        /// 值“27”出栈,并被赋给索引位置“0”处的局部变量 cube,
30                        /// 即内存中变量 cube 的值为“27”。

31    IL_0007:  ldloc.0    /**//**//**//// 局部变量 cube 的值“27”入栈。
32    IL_0008:  call       void [mscorlib]System.Console::WriteLine(int32)
33                        /**//**//**//// 控制台输出堆栈最顶上的 32 位整数“27”。
34    IL_000d:  nop    /**//**//**//// no operation.
35    IL_000e:  ret    /**//**//**//// return from method.
36  }
// end of method Program::PrintCube
37//示例二:把字符串拆分成字符,并按顺序每行输出一个字符
38public void SeparateString( string source )
39{
40    if( source == null )
41        return;
42
43    int count = source.Length;
44
45    char c;
46    for( int i = 0; i < count; i++ )
47    {
48        c = source[ i ];
49        Console.WriteLine( c );
50    }

51}

52
53.method public hidebysig instance void
54          SeparateString(string source) cil managed
55  {
56    // 代码大小       55 (0x37)
57    .maxstack  2
58    .locals init ([0] int32 count,
59             [1] char c,
60             [2] int32 i,
61             [3] bool CS$4$0000)    /**//**//**//// 索引为“3”的这个布尔型局部变量在 C# 代
62                                    /// 码中并未显式声明,是编译器编译时添加的,
63                                    /// 用于保存执行过程中布尔运算的结果,比如比
64                                    /// 较 source 是否为空时,以及比较 i<count 时。
65    IL_0000:  nop

66    IL_0001:  ldarg.1    /**//**//**//// 方法参数 source 的值入栈。
67    IL_0002:  ldnull    /**//**//**//// “空引用”null入栈。
68    IL_0003:  ceq    /**//**//**//// compare equal 比较栈顶的 null 和第二项的 source 是否相等,并
69                    /// 把结果 0(false,source 不为空)或 1(true,source 为空)入栈。

70    IL_0005:  ldc.i4.0    /**//**//**//// 32 位整型数“0”入栈。
71    IL_0006:  ceq    /**//**//**//// 比较栈顶的“0”和堆栈的第二项,第二项可能是“0”,也可能
72                    /// 是“1”。比较的结果“1”或“0”入栈。

73    IL_0008:  stloc.3    /**//**//**//// 栈顶的“1”或“0”出栈,被保存到索引为“3”的局部变量中。
74    IL_0009:  ldloc.3    /**//**//**//// 执行后,栈顶为“1”(source 不为空)或“0”(source 为空)。
75    IL_000a:  brtrue.s   IL_000e    /**//**//**//// branch on non-false or non-null 判断栈顶是否
76                                    /// 为“1”,如果是,跳转到第“IL_000e”行;否则
77                                    /// 继续往下执行。

78
79    IL_000c:  br.s       IL_0036    /**//**//**//// unconditional branch 当栈顶为“0”时,才会
80                                    /// 执行到这一行,这一行的执行结果是程序无条件
81                                    /// 跳转到第“IL_0036”行。

82
83    IL_000e:  ldarg.1
84    IL_000f:  callvirt   instance int32 [mscorlib]System.String::get_Length()   
85                        /**//**//**//// 对堆栈最顶上的字符串调用其获取长度的实例方法,长度值被入栈。
86                        /// “get_Length()”实际是字符串 Length 属性的“get”部分。

87    IL_0014:  stloc.0    /**//**//**//// 局部变量 count 被赋值为字符串长度。
88    IL_0015:  ldc.i4.0
89    IL_0016:  stloc.2    /**//**//**//// 局部变量 i 被赋值为 0。
90    IL_0017:  br.s       IL_002e    /**//**//**//// 无条件跳转到第“IL_002e”行。
91
92    IL_0019:  nop
93    IL_001a:  ldarg.1
94    IL_001b:  ldloc.2
95    IL_001c:  callvirt   instance char [mscorlib]System.String::get_Chars(int32)   
96                        /**//**//**//// source 中索引为 i 处的 char 值入栈。
97    IL_0021:  stloc.1
98    IL_0022:  ldloc.1
99    IL_0023:  call       void [mscorlib]System.Console::WriteLine(char)    /**//**//**//// char 值被输
100                                                                        /// 出到控制台。

101    IL_0028:  nop
102    IL_0029:  nop
103    IL_002a:  ldloc.2    /**//**//**//// i 值入栈。
104    IL_002b:  ldc.i4.1    /**//**//**//// 32 位整数 1 入栈。
105    IL_002c:  add    /**//**//**//// i+1 的结果入栈。
106    IL_002d:  stloc.2    /**//**//**//// i=i+1。
107    IL_002e:  ldloc.2    /**//**//**//// i 值入栈。
108    IL_002f:  ldloc.0    /**//**//**//// count 值入栈。
109    IL_0030:  clt    /**//**//**//// compare less than 比较 i<count 是否为真,比较结果入栈。
110    IL_0032:  stloc.3

111    IL_0033:  ldloc.3
112    IL_0034:  brtrue.s   IL_0019    /**//**//**//// 如果 i<count 则跳转到第“IL_0019”行。
113

114    IL_0036:  ret
115  }
// end of method Program::SeparateString
116
117
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值