IL 代码,有人帮我解释一下为什么 ldarg.0 出现两次?
IL code, Someone get me explain why ldarg.0 appear twice?
这是c#代码
class SimpleIL {
private int f = 2;
public void M1() { M2(f); }
public void M2(Object p) { Console.WriteLine(p); }
}
这是M1方法的IL
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
我的问题是:为什么两次 ldarg.0?
Ldarg.0
在实例方法中是 this
。
一个是获取f
,一个是调用M2
.
(技术上首先使用第二个,因为当访问 f
时它位于堆栈的顶部)
第二个也可以放在调用之前,但这并不重要 - 它只需要在调用时位于堆栈顶部即可。
第一个 ldarg.0
将 this
指针作为 M2
调用的 this
参数加载到堆栈上。
第二个 ldarg.0
加载 this
指针以访问 f
字段。
IL 代码可以这样分组:
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
要使用 IL 调用方法,您可以这样做:
load instance reference on the stack
load argument values on the stack
call method
这里先将"instance reference"加载到栈中,然后添加获取参数值的代码,其中还涉及到获取栈上的实例引用,然后才是使用实例引用的实际调用.
这是c#代码
class SimpleIL {
private int f = 2;
public void M1() { M2(f); }
public void M2(Object p) { Console.WriteLine(p); }
}
这是M1方法的IL
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
我的问题是:为什么两次 ldarg.0?
Ldarg.0
在实例方法中是 this
。
一个是获取f
,一个是调用M2
.
(技术上首先使用第二个,因为当访问 f
时它位于堆栈的顶部)
第二个也可以放在调用之前,但这并不重要 - 它只需要在调用时位于堆栈顶部即可。
第一个 ldarg.0
将 this
指针作为 M2
调用的 this
参数加载到堆栈上。
第二个 ldarg.0
加载 this
指针以访问 f
字段。
IL 代码可以这样分组:
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
要使用 IL 调用方法,您可以这样做:
load instance reference on the stack
load argument values on the stack
call method
这里先将"instance reference"加载到栈中,然后添加获取参数值的代码,其中还涉及到获取栈上的实例引用,然后才是使用实例引用的实际调用.