我正在写一些自定义IL并需要相当于的东西return SomeStaticField != null;.这是我的自然结论:
volatile.ldsfld ...SomeStaticField //volatile is needed here for unrelated reasons
ldnull
ceq
not
ret
Run Code Online (Sandbox Code Playgroud)
但是,这似乎不起作用.我确认SomeStaticField为null,但是这个函数最终会返回true.我知道C#使用分支来构建这样的构造,我也可以使用它,但它让我感到困惑的是为什么这不会有预期的行为
一个完整且可验证的示例(作为库):
.assembly extern /*23000001*/ mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly 'BareMetal'
{
.custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::'.ctor'() = (
01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004
.ver 1:0:0:0
}
.module BareMetal.dll
.namespace Earlz.BareMetal
{
.class public auto ansi abstract sealed beforefieldinit BareMetal
extends [mscorlib]System.Object
{
.method public static hidebysig
default bool FooTest () cil managed
{
.maxstack 2
ldnull
ldnull
ceq
not
ret
}
}
}
Run Code Online (Sandbox Code Playgroud)
not计算其操作数的按位补码:~1is -2,其为非零,为真.否定布尔值的规范方法是ldc.i4.0 ; ceq.
并且,正如@HansPassant指出的那样,!= null直接进行比较的规范方法是cgt.un- 当解释为无符号值时,所有有效引用都"大于零".ECMA-335第I.12.1.5节明确记录了这种比较是安全的:
特别是,对象引用可以是:
...
- 创建为空引用(
ldnull)...
托管指针有几个额外的基本操作.
...
- 无符号比较并基于两个管理指针(条件分支
bge.un,bge.un.s,bgt.un,bgt.un.s,ble.un,ble.un.s,blt.un,blt.un.s,cgt.un,clt.un).
| 归档时间: |
|
| 查看次数: |
244 次 |
| 最近记录: |