[英]What is the meaning of -2 in this IL instruction?
我發現了一個簡單程序的IL code
:
long x = 0;
for(long i = 0;i< int.MaxValue * 2L; i++)
{
x = i;
}
Console.WriteLine(x);
我在發布模式下構建此代碼,並生成此IL code
:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 28 (0x1c)
.maxstack 2
.locals init ([0] int64 x,
[1] int64 i)
IL_0000: ldc.i4.0
IL_0001: conv.i8
IL_0002: stloc.0
IL_0003: ldc.i4.0
IL_0004: conv.i8
IL_0005: stloc.1
IL_0006: br.s IL_000f
IL_0008: ldloc.1
IL_0009: stloc.0
IL_000a: ldloc.1
IL_000b: ldc.i4.1
IL_000c: conv.i8
IL_000d: add
IL_000e: stloc.1
IL_000f: ldloc.1
IL_0010: ldc.i4.s -2
IL_0012: conv.u8
IL_0013: blt.s IL_0008
IL_0015: ldloc.0
IL_0016: call void [mscorlib]System.Console::WriteLine(int64)
IL_001b: ret
} // end of method Program::Main
除了這個,我幾乎找出了所有的解釋:
IL_0010: ldc.i4.s -2
現在這個insruction應該將int.MaxValue * 2L
推入堆棧然后blt.s
將它與i
進行比較,如果i
小於該值則返回到IL_0008
。但是,我無法弄清楚的是為什么它載荷-2 ? 如果我改變循環如下:
for(long i = 0;i < int.MaxValue * 3L; i++)
{
x = i;
}
它加載預期值:
IL_0010: ldc.i8 0x17ffffffd
那么這個代碼中-2
的含義是什么?
int.MaxValue * 2L
是一個64位數字,但仍然適合32位( 4,294,967,294
或0xFFFFFFFE
)。 因此,編譯器加載0xFFFFFFFE
(當解釋為Int32
時等於-2),然后將其擴展為無符號的64位值。
它使用帶符號形式的原因是,當被解釋為有符號值-2
時,該數字適合單個帶符號的字節( -128
到127
),這意味着編譯器能夠發出短形式ldc.i4.s
操作碼從單個字節加載32位值。 它只需要2個字節來加載32位有符號整數,另外1個字節將其轉換為64位值 - 這比使用64位加載指令后跟一個完整的8字節無符號整數要好得多。
看起來編譯器正在使用按位數學來發揮它的優勢。 碰巧的是, Two的Complement值-2等於(int.MaxValue * 2L)的無符號整數值
在按位表示:
- 1111 1111 1111 1111 1111 1111 1111 1110 (int)
- 1111 1111 1111 1111 1111 1111 1111 1110 (uint)
- 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1110 (long
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.