即使没有参数,也会使用CIL OpCode (Ldarg_0)

本文关键字:OpCode Ldarg CIL 参数 | 更新日期: 2023-09-27 18:11:48

我有以下c#代码:

public void HelloWorld()
{
    Add(2, 2);
}
public void Add(int a, int b)
{
    //Do something
}

生成以下CIL

.method public hidebysig instance void  HelloWorld() cil managed
{
  // Code size       11 (0xb)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldc.i4.2
  IL_0003:  ldc.i4.2
  IL_0004:  call       instance void ConsoleApplication3.Program::Add(int32,
                                                                      int32)
  IL_0009:  nop
  IL_000a:  ret
} // end of method Program::HelloWorld

现在,我不明白的是偏移量0001:

ldarg.0

我知道那个操作码是做什么的,但是我真的不明白为什么它在这个方法中被使用,因为没有参数,对吧?

有人知道为什么吗?:)

即使没有参数,也会使用CIL OpCode (Ldarg_0)

在实例方法中有一个索引为0的隐式参数,表示调用该方法的实例。它可以使用ldarg.0操作码加载到IL计算堆栈上。

我认为ldarg.0正在将this加载到堆栈上。看看这个答案MSIL问题(基础)

偏移量0001处的行:将索引0处的参数加载到求值堆栈中。

参见:http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldarg_0.aspx

索引0处的参数是包含的classinstance方法HelloWorldAdd,作为this(或self in other)languajes)

 IL_0001:  ldarg.0   //Loads the argument at index 0 onto the evaluation stack.
 IL_0002:  ldc.i4.2  //Pushes a value 2 of type int32 onto the evaluation stack.
 IL_0003:  ldc.i4.2  //Pushes a value 2 of type int32 onto the evaluation stack.
 IL_0004:  call instance void ConsoleApplication3.Program::Add(int32, int32)

…最后一行是c#中的call: this.Add(2,2);