Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While loop in IL - why stloc.0 and ldloc.0?

Tags:

.net

cil

I'm trying to understand how a while loop looks in IL. I have written this C# function:

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

The IL looks like this:

.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

For the most part this is really simple, except for the part after cgt.

What I don't understand is the local [0] and the stloc.0/ldloc.0. As far as I see it, cgt pushes the result to the stack, stloc.0 gets the result from the stack into the local variable, ldloc.0 pushes the result to the stack again and brtrue.s reads from the stack.

What is the purpose of doing this? Couldn't this be shortened to just cgt followed by brtrue.s?

like image 605
Michael Stum Avatar asked Apr 09 '10 04:04

Michael Stum


2 Answers

Try compiling with optimizations.

like image 98
Ben Voigt Avatar answered Nov 14 '22 20:11

Ben Voigt


That is a debug build (from the nop). All bets are off, but it looks like it is simply introducing a bool variable for simplicity:

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

Build in release with optimisations enabled, which should remove such variables.

like image 5
Marc Gravell Avatar answered Nov 14 '22 19:11

Marc Gravell