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