为什么.MaxStack指令在MSIL代码中是可选的?

时间:2012-03-23 20:21:34

标签: .net cil

我在业余时间学习汇编语言。谁能解释为什么.maxstack在这个程序中似乎是可选的。我试图在网上和我的书中找到答案没有这么幸运,即程序将编译并运行.Maxstack注释掉:

//Add.il
//Add Two Numbers

.assembly extern mscorlib {}

.assembly Add
{
    .ver 1:0:1:0
}
.module add.exe

.method static void main() cil managed
{
    //.maxstack 2
    .entrypoint

    ldstr "The sum of 50 and 30 is = "
    call void [mscorlib]System.Console::Write (string)

    ldc.i4.s 50
    ldc.i4 30    
    add
    call void [mscorlib]System.Console::Write (int32)
    ret
}

我正在使用ILASM工具在命令行编译程序,然后运行生成的可执行文件。

2 个答案:

答案 0 :(得分:13)

我认为你的困惑源于对.maxstack实际做什么的误解。这是一个容易犯的错误,因为它似乎会在执行时导致错误。令人惊讶的是,该特定指令实际上在运行时没有与堆栈大小相关,而是在代码验证期间专门使用它。

来自分区III - 第1.7.4节

  

注意:Maxstack与程序分析有关,而与运行时堆栈的大小无关。它没有指定堆栈帧的最大字节数,而是指定分析工具必须跟踪的项目数。

代码变为无法验证。同一部分指出,任何符合要求的实现都不需要支持具有无效最大堆栈值的方法。但是,它并没有说它一定不能,而且很明显,运行时正在执行代码。所以,如果它似乎没有效果,为什么还要费心呢?

信不信由你,默认,.NET框架运行无法验证的代码。实际上我很难弄清楚如何在.NET 4.0中启用验证,但如果你打开CAS,你的程序(.maxstack 1)将停止运行

  

未处理的异常:System.InvalidProgramException:公共语言运行时检测到无效的程序。     在main()

记住这一点,无法验证的代码无法在任何没有完全信任的环境中运行(通常是来自Internet的程序集)。如果这对你来说不重要,你可以让它成为一个无效的价值,它实际上不会产生任何影响。如果代码本身仍然正确,它将正常运行;当然,如果IL堆栈实际上存在问题,它将抛出InvalidProgramException

答案 1 :(得分:0)

如果我没记错的话,如果省略该语句,则默认堆栈大小为8。