Search code examples
.net-assemblycil

Why is it loading both ldarg.0 and ldarg.1 when there are only 1 argument?


I am quite confused how this assembly code works. I have tried looking around for answers but couldn't find anything. I think ldarg.0 is loaded due to an instance void, but i'm not sure why it loads ldarg.1.

Would really appreciate it if someone could explain what's going on.

.method public hidebysig specialname instance void set_phase(string value)
  {
    .maxstack 3
    .locals init (bool V0)
nop
ldarg.1
ldarg.0
ldfld    string KGER.Generate::_phase
call     bool [mscorlib]System.String::op_Inequality(string, string)
ldc.i4.0
ceq
stloc.0
ldloc.0
brtrue.s loc_4E8

Thanks in advance!


Solution

  • Your code is not complete, however: the portion does the following:

    .method public hidebysig specialname instance void set_phase(string value)
      {
        .maxstack 3
        .locals init (bool V0)
    

    This is the method signature. from here you infer two important things: the first is that the method is an instance method. This means that the first implicit argument contains this. The second important thing is the signature which consists of a single argument of type string: this will be arg1 as arg0 is implicitly used to contain this.

    nop
    

    computationally, this does nothing. among other things, nop instructions can be used by debuggers to safely place break points

    ldarg.1
    

    this loads arg1 onto the stack. The stack contains (the value of the field named value)

    ldarg.0
    ldfld    string KGER.Generate::_phase
    

    then loads the this argument and immediately uses it to load the KGER.Generate::_phase field. the stack now contains (value, the content of the _phase field)

    call     bool [mscorlib]System.String::op_Inequality(string, string)
    

    this calls the operator op_Inequality of the class String which is a static method. the stack now contains (result of comparison)

    ldc.i4.0
    

    this loads 0 as integer into the stack. as we know that this value will be part of a boolean comparison, remember that 0 is equivalent to false for these purposes

    ceq
    

    this compares the two values into the stack and pushes the result as boolean into the stack

    stloc.0
    

    this stores the result of the comparison to a local variable (the first one)

    ldloc.0
    

    this loads the result of the comparison stored to the abovementioned local variable again into the stack, presumably this is a debug version, and this pair of instructions allows the developer to correctly view the value of the variables while debugging (or it is really needed in a part of code you didn't share)

    brtrue.s loc_4E8
    

    this jumps to the location loc_4E8 when the value is true (i.e. 1), which means that if thee two strings are equal, the code will jump.