【发布时间】:2011-10-06 09:46:02
【问题描述】:
如果我有一个方法Multiply 定义为:
public static class Experiment
{
public static int Multiply(int a, int b)
{
return a * b;
}
}
那为什么编译器会发出这个 IL:
.method public hidebysig static int32 Multiply(int32 a, int32 b) cil managed
{
.maxstack 2 //why is it not 16?
.locals init (
[0] int32 CS$1$0000) //what is this?
L_0000: nop //why this?
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: mul
L_0004: stloc.0 //why this?
L_0005: br.s L_0007 //why this?
L_0007: ldloc.0 //why this?
L_0008: ret
}
如您所见,它还包含一些对我来说没有意义的附加操作码,而实际上我期望以下 IL:
.method public hidebysig static int32 MyMethod(int32 a, int32 b) cil managed
{
.maxstack 16
L_0000: ldarg.0
L_0001: ldarg.1
L_0002: mul
L_0003: ret
}
做同样的事情。
那么问题来了,为什么编译器会在 IL 中发出额外的操作码?
我正在使用调试模式。
【问题讨论】:
-
调试或发布配置?
-
至少
NOP仅用于调试并创建某种序列点,JITter 可能无法在该序列点上重新排序指令。这有助于调试。 -
我假设您在@Alex 提出上述问题后以发布模式重新编译?
-
@LasseV.Karlsen:是的。它不再包含它们。但我仍然对调试模式构建感到好奇,并发出了 IL。