我很困惑这个汇编代码是如何工作的。我尝试四处寻找答案,但找不到任何东西。我认为 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
,这意味着如果两个字符串相等,则代码将跳转。