gpt4 book ai didi

c# - 这条IL指令中的-2是什么意思?

转载 作者:太空狗 更新时间:2023-10-29 18:14:52 27 4
gpt4 key购买 nike

我发现了一个简单程序的 IL 代码:

long x = 0;
for(long i = 0;i< int.MaxValue * 2L; i++)
{
x = i;
}

Console.WriteLine(x);

我在Release 模式下构建此代码并生成此IL 代码:

.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

现在这条指令应该将 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 位值的操作码。加载 32 位有符号整数只需要 2 个字节,另外需要 1 个字节将其转换为 64 位值——这比使用 64 位加载指令后跟一个完整的 8 字节无符号整数要好得多。

关于c# - 这条IL指令中的-2是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26801968/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com