Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IL code, Someone get me explain why ldarg.0 appear twice?

Tags:

c#

il

This is the c# code

class SimpleIL { 
        private int f = 2; 
        public void M1() { M2(f); } 
        public void M2(Object p) { Console.WriteLine(p); } 
}

This is the IL of M1 method

 IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.0
  IL_0003:  ldfld      int32 ConsoleApplication1.SimpleIL::f
  IL_0008:  box        [mscorlib]System.Int32
  IL_000d:  call       instance void ConsoleApplication1.SimpleIL::M2(object)
  IL_0012:  nop
  IL_0013:  ret

My question is: Why twice ldarg.0?

like image 538
StevenS Avatar asked Sep 13 '15 15:09

StevenS


3 Answers

Ldarg.0 is this in an instance method.

One is to get f, the other is to call M2.

(Technically the second is used first as it is at the top of the stack when f is accessed)

The second could as well be placed just before the call but it doesn't really matter - it just has to be on top of the stack when the call is made.

like image 53
Wiktor Zychla Avatar answered Oct 22 '22 05:10

Wiktor Zychla


The IL code can be grouped like this:

IL_0000:  nop

    IL_0001:  ldarg.0

        // get the value for the parameter
        IL_0002:  ldarg.0
        IL_0003:  ldfld      int32 ConsoleApplication1.SimpleIL::f
        IL_0008:  box        [mscorlib]System.Int32

    // call "this.M2(...)", this is already on the stack from before
    IL_000d:  call       instance void ConsoleApplication1.SimpleIL::M2(object)

IL_0012:  nop
IL_0013:  ret

To call a method using IL you do this:

load instance reference on the stack
load argument values on the stack
call method

Here the "instance reference" was loaded onto the stack first, then code to obtain the parameter value was added, which also involved getting an instance reference on the stack, followed by the actual call that uses the instance reference.

like image 37
Lasse V. Karlsen Avatar answered Oct 22 '22 05:10

Lasse V. Karlsen


The first ldarg.0 loads the this pointer as the this argument for the M2 call onto the stack.

The second ldarg.0 loads the this pointer for accessing the f field.

like image 3
500 - Internal Server Error Avatar answered Oct 22 '22 06:10

500 - Internal Server Error