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

  • 本文关键字:ldarg 加载 参数 .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

提前感谢!

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

.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加载到堆栈上。堆栈包含(名为值的字段的值)

ldarg.0
ldfld    string KGER.Generate::_phase

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

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

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

ldc.i4.0

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

ceq

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

stloc.0

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

ldloc.0

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

brtrue.s loc_4E8

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

相关内容

  • 没有找到相关文章

最新更新