assembly 在Visual Studio 2010下为x64构建的本机C代码中存在无法解释的堆栈分配

ylamdve6  于 2022-12-13  发布在  其他
关注(0)|答案(2)|浏览(134)

我尝试使用CL 16.0 for x64(VS 2010)生成一些可读的64位ASM代码作为示例,但CL坚持预先分配大量堆栈空间(28 h字节),使用以下行:

sub rsp, 40 ; 00000028H (actual value depends on number of local vars of course)

问题是,我如何禁用此行为?这很难向类解释,我喜欢向他们展示干净、可解释的代码...我的假设是“sub rsp,XXX”应该分配函数中局部变量所需的确切空间。
当然,它不需要额外的空间。在x86上,这种行为似乎是由编辑并继续开关(/Zi与/ZI)控制的,但在x64的情况下,这些开关没有任何作用。有什么想法可以让x64 CL只分配它实际需要的堆栈吗?
提前感谢!

qyyhg6bp

qyyhg6bp1#

如果你展示产生这个的源代码会更容易一些,但是40字节对于64位机器来说并不多。这仅仅是5个long或指针。另一件要考虑的事情是局部变量的对齐--编译器可能会填充它们以优化访问。

编辑:

嗯,这确实有点令人费解。通过愚者运行它并不会导致这样的堆栈抓取。我怀疑这是编译器特定的异常处理prolog要求(在生成的代码中,在堆栈分配之前和之后,您是否看到一些看起来奇怪的标签?)
以下是几个您可能会觉得有用的MSDN链接:

我没有一个Windows的盒子来测试,但是尝试一下/favor:???,看看把优化级别提高一点是否可以消除这个问题。
此外,对SO的评论格式很糟糕,把代码放到问题本身。

tkqqtvp1

tkqqtvp12#

它叫做影空间
Win 64中的每一个函数都可以(尽管不是必须)在那里存储4个寄存器的值。这样做至少有两个原因
1.在大型函数中,为输入参数分配整个寄存器(更少的4个寄存器)太浪费了,因此它将通过堆栈访问;
1.调试器总是知道在哪里找到函数的参数。
因此,一些大型函数可能会将输入参数保存在“影子空间”中以备将来使用,而像我们这样的小函数则不会。是调用者在堆栈中为“影子空间”分配空间。

相关问题