[英]Analyzing MSIL code generated from C#
I have the following function: 我有以下功能:
public string MyPhrase(int val)
{
if ((val %3 == 0) && (val % 6 == 0))
return "Fizz Bang";
if (val % 3 == 0)
return "Fizz";
if (val % 6 == 0)
return "Bang";
return "";
}
After compiling this and viewing it with IlDasm, I get this output: 编译并使用IlDasm对其进行查看后,我得到以下输出:
IL_0000: ldarg.1
IL_0001: ldc.i4.3
IL_0002: rem
IL_0003: brtrue.s IL_0010
IL_0005: ldarg.1
IL_0006: ldc.i4.6
IL_0007: rem
IL_0008: brtrue.s IL_0010
IL_000a: ldstr "Fizz Bang"
IL_000f: ret
IL_0010: ldarg.1
IL_0011: ldc.i4.3
IL_0012: rem
IL_0013: brtrue.s IL_001b
IL_0015: ldstr "Fizz"
IL_001a: ret
IL_001b: ldarg.1
IL_001c: ldc.i4.6
IL_001d: rem
IL_001e: brtrue.s IL_0026
IL_0020: ldstr "Bang"
IL_0025: ret
IL_0026: ldstr ""
IL_002b: ret
From looking at this page , brtrue
will branch if true. 通过查看此页面 , brtrue
如果为true,将分支。 What's confusing me is the line IL_0003
. 使我感到困惑的是IL_0003
行。 Its saying that it should branch to line IL_0010
if its true. 俗话说,如果为真,则应分支到第IL_0010
行。 In my C# code though, I am using an &&
to compare two expressions before my program flow should jump to the next if
. 但是在我的C#代码中,我使用&&
比较两个表达式,然后程序流应跳至下一个if
。 It seems backwards. 似乎倒退了。 From the MSIL code posted, it seems like its checking to see if my operation is true and if it is, its jumping to my next if
block, which would be logically wrong. 从发布的MSIL代码中,似乎要检查我的操作是否正确,如果是,则跳转到下一个if
块,这在逻辑上是错误的。 Can someone explain what I'm missing? 有人可以解释我所缺少的吗?
This is a side-effect of short circuit evaluation for the && operator. 这是&&运算符的短路评估的副作用。 Which promises that the right-hand expression of the operator does not get evaluated if the left-hand side is false. 这保证如果左侧为假,则不会对运算符的右侧表达式求值。 So you see it skip the val % 6 == 0 expression and the return "Fizz Bang" statement if the REM opcode returns a non-zero result. 因此,您将看到它跳过val%6 == 0表达式,并且在REM操作码返回非零结果时返回“ Fizz Bang”语句。
brtrue.s transfers control to the given target if the value on the stack is non-zero. 如果堆栈上的值不为零,则brtrue.s会将控制权转移到给定的目标。
so, In your IL code IL_0003
is tranfers control to IL_0010
. 因此,在您的IL代码IL_0003
控制权转移到IL_0010
。 means (val % 3 == 0) condition return false. 表示(val%3 == 0)条件返回false。 you used &&
in first if condition if ((val %3 == 0) && (val % 6 == 0))
so, on first condition (val % 3 == 0)
return false, second condition will not check 您在第一个条件中使用&&
if条件if ((val %3 == 0) && (val % 6 == 0))
如此,在第一个条件(val % 3 == 0)
返回false时,第二个条件将不检查
IL_0005: ldarg.1
IL_0006: ldc.i4.6
IL_0007: rem
IL_0008: brtrue.s IL_0010
and control transfer to IL_0010
并将控制权转移到IL_0010
IL_0010: ldarg.1
IL_0011: ldc.i4.3
IL_0012: rem
IL_0013: brtrue.s IL_001b
check out this for more information: http://weblogs.asp.net/kennykerr/archive/2004/09/23/introduction-to-msil-part-6-common-language-constructs.aspx 请查看此以获取更多信息: http : //weblogs.asp.net/kennykerr/archive/2004/09/23/introduction-to-msil-part-6-common-language-constructs.aspx
This blok load arguments data from Stack, before begin comparing 开始比较之前,此方法从Stack加载参数数据
So it's normal to jump to this section of loading data 因此,跳转到此部分加载数据是正常的
IL_0010: ldarg.1
IL_0011: ldc.i4.3
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.