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

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

我很困惑这段汇编代码是如何工作的。我试过四处寻找答案,但找不到任何东西。我认为 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

提前致谢!

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

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

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

nop

在计算上,这没有任何作用。除此之外,nop 指令可以被调试器用来安全地放置断点

ldarg.1

这会将 arg1 加载到堆栈上。堆栈包含(名为 value 的字段的值)

ldarg.0
ldfld    string KGER.Generate::_phase

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

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

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

ldc.i4.0

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

ceq

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

stloc.0

这存储了与局部变量(第一个)比较的结果

ldloc.0

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

brtrue.s loc_4E8

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