【发布时间】:2016-02-14 19:55:56
【问题描述】:
所以我查看了 ILDASM,检查了一个如下所示的 .exe:
int a = 2;
Int32 b = 1;
if(b == 1)
{
}
现在,CIL 代码如下所示:
IL_0005: ldloc.1
IL_0006: ldc.i4.1
IL_0007: ceq
IL_0009: ldc.i4.0
IL_000a: ceq
IL_000c: stloc.2
我知道首先加载 b(存储在 [1] 中),然后加载一个值为 1 的常量,然后将它们进行比较。我不明白为什么在存储比较结果之前加载和比较另一个值为 0 的常量。
由于第一次比较应该已经产生了一个真值,所以检查这个值是否为 0 会反转结果,对吧?
我现在的问题是:为什么它是倒置的?
我认为它与我使用的 == 运算符有关,我的理论是它返回差异。如果此差异为 0,则值相同,因此结果应为 true。但是0代表假,所以需要取反。
我似乎找不到任何关于这个话题的东西,只是关于像 ==~ 这样的运算符的东西。
希望大家多多指教:)
最好的问候
威尔苏
PS:这是完整的代码:
.method private hidebysig instance void Form1_Load(object sender,
class [mscorlib]
System.EventArgs e) cil managed
{
// Code size 19 (0x13)
.maxstack 2
.locals init ([0] int32 a,
[1] int32 b,
[2] bool CS$4$0000)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ldc.i4.1
IL_0004: stloc.1
IL_0005: ldloc.1
IL_0006: ldc.i4.1
IL_0007: ceq
IL_0009: ldc.i4.0
IL_000a: ceq
IL_000c: stloc.2
IL_000d: ldloc.2
IL_000e: brtrue.s IL_0012
IL_0010: nop
IL_0011: nop
IL_0012: ret
} // end of method Form1::Form1_Load
【问题讨论】:
-
我根本没有得到那个 IL。我的猜测是它来自另一段代码。请发布一个简短但完整的示例。
-
我得到了相同的(至少相似的结果)只有这个代码在 main.
-
你正在编译发布吗? (我没有看到任何“nop”,但是...),并且:这是整个代码吗?看起来它做了一些有趣的重新排序;p 但是:我没有看到第三个变量,所以对我来说
stloc.2甚至 意味着... 并不明显...跨度> -
我非常确信您正在查看调试版本;简短的回答是:它做了很多不必要的事情使调试更容易。您不应该过多关注调试版本中的 IL。
-
这不是完整的代码。我从 IL_0005 开始,上面有 4 行,还有 .maxstack 2 和 .locals init。其余的代码太长了,无法评论……我会把它添加到我的问题中。
标签: c# operators cil comparison-operators