为什么在ILASM反汇编中省略了一些行标签?

Why some line labels in ILASM disassembly are omitted?

我使用 telerik JD 反汇编了一些代码,我注意到一些标签被省略了,并且部分代码没有用。

IL:

    .method assembly hidebysig instance void xxx (
        int32 p_intPer
    ) cil managed noinlining 
{
    IL_0000: br.s IL_000a

    IL_0002: call

    IL_0007: ldnull
    IL_0008: ldind.ref
    IL_0009: pop

    IL_000a: ldc.i4.0
    IL_000b: brtrue.s IL_0007
    .try
    {
        IL_000d: ldarg.0
        IL_000e: ldfld class [Reader]aaa bbb::getP 
        IL_0013: brfalse IL_0024

        IL_0018: ldarg.0
        IL_0019: ldfld class [Reader]aaa bbb::getP 
        IL_001e: ldarg.1
        IL_001f: callvirt instance void [Reader]aaa::Invoke(int32)

        IL_0024: leave IL_002f
    }
    catch [mscorlib]System.Object
    {
        IL_0029: pop
        IL_002a: leave IL_002f
    }

    IL_002f: ret
}

C#:

        internal void xxx(int per)
    {
        while (0 != 0) { }
        try
        {
            if (this.getP != null)
            {
                this.getP(per);
            }
        }
        catch { }
    }

我是说IL_0000 -> IL_0002 -> IL_0007

是反编译器傻了,还是正常? 另外,我对 IL 不是很熟练,但这对我来说看起来不像实际的 C# 源代码

标签偶尔跳过几个数字是正常的,并非每条指令的大小都相同。

标签中的数字是后续指令的方法体中的偏移量。但并非每条指令和操作数的大小都相同。

  • IL_0000: br.s 1字节操作码 1字节操作数
  • IL_0002:调用1byte操作码4byte操作数
  • IL_0007: ldnull 1 字节操作码
  • IL_0008: ldind.ref 1 字节操作码
  • [...]