为什么只有1个参数时才同时加载ldarg.0和ldarg.1?

时间:2019-06-15 21:02:12

标签: .net-assembly cil

我很困惑此汇编代码的工作方式。我尝试到处寻找答案,但找不到任何东西。我认为由于实例无效而加载了ldarg.0,但我不确定为什么要加载ldarg.1。

如果有人可以解释发生了什么,我将非常感谢。

.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

谢谢!

1 个答案:

答案 0 :(得分:0)

您的代码不完整,但是:该部分执行以下操作:

这是方法签名。从这里您可以推断出两个重要的事情:首先是该方法是instance方法。这意味着第一个隐式参数包含this。 第二个重要的事情是签名,它由一个字符串类型的单个参数组成:这将是arg1,因为arg0被隐式地用来包含this

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

计算上,这什么也没做。除其他外,nop指令可被调试器用来安全地放置断点

nop

这会将arg1加载到堆栈中。堆栈包含(名为值的字段的值)     ldarg.1

然后加载this参数,并立即使用它加载KGER.Generate::_phase字段。堆栈现在包含(值, _phase字段的内容

ldarg.0
ldfld    string KGER.Generate::_phase

这将调用类op_Inequality的运算符String,它是一个静态方法。堆栈现在包含(比较结果

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

这会将0作为整数加载到堆栈中。我们知道此值将是布尔比较的一部分,请记住0等于false出于这些目的

ldc.i4.0

这会将两个值比较到堆栈中,并将结果作为布尔值推入堆栈中     ceq

这会将比较结果存储到局部变量(第一个)     stloc.0

这会将存储到上述本地变量的比较结果再次加载到堆栈中,大概是调试版本,这对指令允许开发人员在调试时正确查看变量的值(或者是确实需要您没有共享的一部分代码)

ldloc.0

当值为loc_4E8(即1)时,它跳转到位置true,这意味着如果两个字符串相等,则代码将跳转。

brtrue.s loc_4E8