簡體   English   中英

這個IL指令中-2的含義是什么?

[英]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,2940xFFFFFFFE )。 因此,編譯器加載0xFFFFFFFE (當解釋為Int32時等於-2),然后將其擴展為無符號的64位值。

它使用帶符號形式的原因是,當被解釋為有符號值-2時,該數字適合單個帶符號的字節( -128127 ),這意味着編譯器能夠發出短形式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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM