Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why there is a ldloc.0 just after stloc.0 in IL code?

Tags:

c#

.net

cil

I`m trying to learn CIL by writing small snippets of code and examining compiled assemblies. So I wrote this simple if statement:

    public static void Main (string[] args)
    {
        Int32 i = Int32.Parse (Console.ReadLine());
        if (i > 0)
            Console.WriteLine ("i is greater than 0");
    }

And C# compiler compiled it into the following IL code:

.method public hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] int32 num,
        [1] bool flag)
    L_0000: nop 
    L_0001: call string [mscorlib]System.Console::ReadLine()
    L_0006: call int32 [mscorlib]System.Int32::Parse(string)
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: ldc.i4.0 
    L_000e: cgt 
    L_0010: ldc.i4.0 
    L_0011: ceq 
    L_0013: stloc.1 
    L_0014: ldloc.1 
    L_0015: brtrue.s L_0022
    L_0017: ldstr "i is greater than 0"
    L_001c: call void [mscorlib]System.Console::WriteLine(string)
    L_0021: nop 
    L_0022: ret 
}

As I know,stloc puts the topmost value from the evaluation stack into the local variable,and,if I got it right,that value isn`t popped from the stack,so why does the compiler puts the ldloc instruction just after it?

like image 353
IDavid Avatar asked Jun 24 '17 06:06

IDavid


1 Answers

It's only in Debug mode that you see those instructions as the compiler doesn't optimize the code so that you can debug and put breakpoints in specific parts.

If you compile this application in Release mode you see that even on IL code there's an optimization is done.

.method public hidebysig static void 
  Main(
    string[] args
  ) cil managed 
{
  .entrypoint
  .maxstack 8

  // [13 13 - 13 55]
  IL_0000: call         string [mscorlib]System.Console::ReadLine()
  IL_0005: call         int32 [mscorlib]System.Int32::Parse(string)

  // [14 13 - 14 23]
  IL_000a: ldc.i4.0     
  IL_000b: ble.s        IL_0017

  // [15 17 - 15 58]
  IL_000d: ldstr        "i is greater than 0"
  IL_0012: call         void [mscorlib]System.Console::WriteLine(string)

  // [16 9 - 16 10]
  IL_0017: ret          

} // end of method Program::Main
like image 156
Paweł Łukasik Avatar answered Nov 01 '22 16:11

Paweł Łukasik