gpt4 book ai didi

c# - 为什么 .maxstack 值在 Release模式 dll/exe 中更多?

转载 作者:太空狗 更新时间:2023-10-29 22:21:34 25 4
gpt4 key购买 nike

我很想了解在 Debug 和 Release 模式下生成的 IL 代码之间的区别。我写了一个简单的代码。

        using System;

namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
int result = int.Parse(Console.ReadLine());
if (true)
{
Console.WriteLine("Hi There");
}
Console.WriteLine("Done");
Console.ReadLine();
}
}
}

我比较了使用 IL Deassembler 生成的 exe。并且发现 .maxstack 值在 Release模式下为 8,在构建模式下为 1。在这里提问之前,我搜索了一些网络文章,发现这里计算了任何操作的堆栈条目数。此外,根据我的理解, Release模式代码是一种更有条理和优化的方式。谁能确认我的理解,如果我错了请告诉我?另外,我想知道,如果 Release模式输出是优化的,为什么堆栈大小会增加?堆栈大小表示什么。谢谢。


以下代码来自 Release模式

        .method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 38 (0x26)
.maxstack 8
IL_0000: call string [mscorlib]System.Console::ReadLine()
IL_0005: call int32 [mscorlib]System.Int32::Parse(string)
IL_000a: pop
IL_000b: ldstr "Hi There"
IL_0010: call void [mscorlib]System.Console::WriteLine(string)
IL_0015: ldstr "Done"
IL_001a: call void [mscorlib]System.Console::WriteLine(string)
IL_001f: call string [mscorlib]System.Console::ReadLine()
IL_0024: pop
IL_0025: ret
} // end of method Program::Main

以下代码来自构建模式

            .method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 45 (0x2d)
.maxstack 1
.locals init ([0] int32 result,
[1] bool CS$4$0000)
IL_0000: nop
IL_0001: call string [mscorlib]System.Console::ReadLine()
IL_0006: call int32 [mscorlib]System.Int32::Parse(string)
IL_000b: stloc.0
IL_000c: ldc.i4.0
IL_000d: stloc.1
IL_000e: nop
IL_000f: ldstr "Hi There"
IL_0014: call void [mscorlib]System.Console::WriteLine(string)
IL_0019: nop
IL_001a: nop
IL_001b: ldstr "Done"
IL_0020: call void [mscorlib]System.Console::WriteLine(string)
IL_0025: nop
IL_0026: call string [mscorlib]System.Console::ReadLine()
IL_002b: pop
IL_002c: ret
} // end of method Program::Main

最佳答案

有两种不同版本的方法头可供编译器选择,Fat 头或 Tiny 头(在 ECMA-335 Part II 中定义,分别参见第 25.4.3 和 25.4.2 节。)

虽然胖头有 12 个字节长,但微型头只有一个字节。它可以通过将 IL 的大小限制为 63 字节、不支持局部变量或异常处理程序以及假设 .maxstack 为 8 来变得这么小。

由于您的调试版本使用局部变量,因此它不符合微型 header 的条件,但您的发布版本对其进行了优化,允许它使用微型 header 并获得假设的 .maxstack 8 而不是比明确提供的更小的 .maxstack

关于c# - 为什么 .maxstack 值在 Release模式 dll/exe 中更多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40399852/

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