В скомпилированном IL нет ярлыков. Вместо этого инструкции перехода используют относительные смещения с начала следующей инструкции.
Для примера рассмотрим этот тривиальный C# функция:
public static bool IsZero(int n)
{
if (n == 0)
return true;
return false;
}
В IL, вы можете написать это так:
.method public hidebysig static bool IsZero(int32 n) cil managed
{
ldarg.0
brtrue.s label
ldc.i4.1
ret
label:
ldc.i4.0
ret
}
Если вы компилируете, что с помощью ILASM, а затем декомпилировать его обратно, используя ILDASM , при включении «Показывать байты» вы получаете:
.method public hidebysig static bool IsZero(int32 n) cil managed
// SIG: 00 01 02 08
{
// Method begins at RVA 0x2052
// Code size 7 (0x7)
.maxstack 8
IL_0000: /* 02 | */ ldarg.0
IL_0001: /* 2D | 02 */ brtrue.s IL_0005
IL_0003: /* 17 | */ ldc.i4.1
IL_0004: /* 2A | */ ret
IL_0005: /* 16 | */ ldc.i4.0
IL_0006: /* 2A | */ ret
} // end of method Program::IsZero
Обратите внимание, что эти метки не находятся в любым способом, представленным в байтах (показано в комментариях). И что brtrue.s label
от оригинального IL здесь изображается как brtrue.s IL_0005
, где байты 2D 02
. 2D
- скомпилированная форма brtrue.s
, а 02
- относительное смещение. Так как следующая инструкция начинается с абсолютного смещения 3, цель находится на абсолютном смещении 3 + 2 = 5.
Что заставляет вас думать, что это ярлык, а не только как ildasm отображает IL? –
, так что это похоже на строку «IL_0001»? @JonSkeet –
@EhsanSajjad: Вид. Я считаю, что они действуют как ярлыки, которые вы * можете использовать в IL, но я не верю, что они находятся в фактическом сгенерированном коде. –