Цикл с условием продолжения в IL - почему stloc.0 и ldloc.0?

Я пытаюсь понять, как некоторое время цикл смотрит в IL. Я записал эту функцию C#:

    static void Brackets()
    {
        while (memory[pointer] > 0)
        {
            // Snipped body of the while loop, as it's not important
        }
    } 

IL похож на это:

.method private hidebysig static void  Brackets() cil managed
{
  // Code size       37 (0x25)
  .maxstack  2
  .locals init ([0] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  br.s       IL_0012
  IL_0003:  nop
  // Snipped body of the while loop, as it's not important
  IL_0011:  nop
  IL_0012:  ldsfld     uint8[] BFHelloWorldCSharp.Program::memory
  IL_0017:  ldsfld     int16 BFHelloWorldCSharp.Program::pointer
  IL_001c:  ldelem.u1
  IL_001d:  ldc.i4.0
  IL_001e:  cgt
  IL_0020:  stloc.0
  IL_0021:  ldloc.0
  IL_0022:  brtrue.s   IL_0003
  IL_0024:  ret
} // end of method Program::Brackets

По большей части это действительно просто, за исключением части после CGT.

То, что я не понимаю, является локальным [0] и stloc.0/ldloc.0. Насколько я вижу его, CGT продвигает результат к стеку, stloc.0 получает результат стека в локальную переменную, ldloc.0 продвигает результат к стеку снова и чтениям brtrue.s от стека.

Какова цель сделать это? Разве это не могло быть сокращено только к CGT, сопровождаемому brtrue.s?

8
задан Michael Stum 9 April 2010 в 04:18
поделиться

2 ответа

Попробуйте скомпилировать с оптимизацией.

6
ответ дан 5 December 2019 в 17:35
поделиться

Это отладочная сборка (из nop ). Все ставки отключены, но похоже, что для простоты просто вводится переменная типа bool:

    goto testforexit;
body:
    ..
testforexit:
    bool tmp = memory[pointer] > 0;
    if(tmp) goto body;

Встроенная версия с включенной оптимизацией, которая должна удалить такие переменные.

4
ответ дан 5 December 2019 в 17:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: