通过MSIL看比较运算符是如何进行的

static void Main(string[] args)
{
    int i = 2;
    int j = 3;

    if (i > j)
        Console.WriteLine("yes");
    else
        Console.WriteLine("no");

    Console.ReadKey();
}

对应的MSIL代码为:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小       47 (0x2f)
  .maxstack  2
  .locals init ([0] int32 i,
           [1] int32 j,
           [2] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldc.i4.2
  IL_0002:  stloc.0
  IL_0003:  ldc.i4.3
  IL_0004:  stloc.1
  IL_0005:  ldloc.0
  IL_0006:  ldloc.1
  IL_0007:  cgt

  IL_0009:  ldc.i4.0
  IL_000a:  ceq
  IL_000c:  stloc.2
  IL_000d:  ldloc.2
  IL_000e:  brtrue.s   IL_001d

  IL_0010:  ldstr      "yes"
  IL_0015:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001a:  nop
  IL_001b:  br.s       IL_0028
  IL_001d:  ldstr      "no"
  IL_0022:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0027:  nop
  IL_0028:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_002d:  pop
  IL_002e:  ret
} // end of method Program::Main

蓝色部分,将数值2赋给第一个局部变量i,将数值3赋给第二个局部变量j,并对它们进行cgt(>)运算,正常理解接下来应该是对运算结果进行判断并分支了。然而事实并不是这样的,再看红色部分,之后加载了一个数值0(相当于false)到内存中,然后将cgt运算结果和0进行ceq(=)运算,并将结果存储到编译器自己声明的一个变量CS$4$0000中,是对CS$4$0000进行判断后再进行分支的。测试了其他比较运算符,也都是会多出一个类似的ceq运算。

评论: 0 | 引用: 0 | 查看次数: 3560
发表评论
登录后再发表评论!