我在业余时间学习汇编语言。谁能解释为什么.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工具在命令行编译程序,然后运行生成的可执行文件。
答案 0 :(得分:13)
我认为你的困惑源于对.maxstack
实际做什么的误解。这是一个容易犯的错误,因为它似乎会在执行时导致错误。令人惊讶的是,该特定指令实际上在运行时没有与堆栈大小相关,而是在代码验证期间专门使用它。
来自分区III - 第1.7.4节
注意:Maxstack与程序分析有关,而与运行时堆栈的大小无关。它没有指定堆栈帧的最大字节数,而是指定分析工具必须跟踪的项目数。
代码变为无法验证。同一部分指出,任何符合要求的实现都不需要支持具有无效最大堆栈值的方法。但是,它并没有说它一定不能,而且很明显,运行时正在执行代码。所以,如果它似乎没有效果,为什么还要费心呢?
信不信由你,默认,.NET框架运行无法验证的代码。实际上我很难弄清楚如何在.NET 4.0中启用验证,但如果你打开CAS,你的程序(.maxstack 1
)将停止运行
未处理的异常:System.InvalidProgramException:公共语言运行时检测到无效的程序。 在main()
记住这一点,无法验证的代码无法在任何没有完全信任的环境中运行(通常是来自Internet的程序集)。如果这对你来说不重要,你可以让它成为一个无效的价值,它实际上不会产生任何影响。如果代码本身仍然正确,它将正常运行;当然,如果IL堆栈实际上存在问题,它将抛出InvalidProgramException
。
答案 1 :(得分:0)
如果我没记错的话,如果省略该语句,则默认堆栈大小为8。