在未优化的MSIL中有多余的NOP和分支

时间:2016-01-13 11:08:30

标签: c# cil il ildasm nop

当我将以下代码编译为debug ...

public class MyClass
{
    private int myField;

    public int MyProperty
    {
        get { return myField; }
        set { myField = value; }
    }
}

...编译器会产生看似无用的奇怪字节码。例如,查看为属性MyProperty的getter生成的内容(用ildasm.exe反汇编):

.method public hidebysig specialname instance int32 
        get_MyProperty() cil managed
{
    // Code size       12 (0xc)
    .maxstack  1
    .locals init ([0] int32 CS$1$0000)
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  ldfld      int32 MSILTest.MyClass::myField
    IL_0007:  stloc.0
    IL_0008:  br.s       IL_000a
    IL_000a:  ldloc.0
    IL_000b:  ret
} // end of method MyClass::get_MyProperty

具体来说,nop IL_0000在那里做什么?为什么编译器在br.s无处不在地生成这个无用的IL_0008指令?为什么要创建临时局部变量CS$1$0000

对于发布配置,指令集按预期生成:

IL_0000:  ldarg.0
IL_0001:  ldfld      int32 MSILTest.MyClass::myField
IL_0006:  ret

修改

我想我已经找到了一个问题的答案,为什么分支和临时局部变量存在于different question中:它可能很容易在调试期间设置断点。所以仍然存在的问题是为什么nop指令得到了治疗。

1 个答案:

答案 0 :(得分:3)

编译器创建这些操作码以提供更好的调试体验。在每个c#行的开头,编译器将引入一个 nop所以调试器可以在那里打破。发出分支和临时局部变量,以便分析函数返回值。