是否为少于四个参数的函数保留了必要的堆栈空间?

Don*_*Don 18 64-bit assembly stack cpu-registers

刚开始学习x64程序集,我对函数,参数和堆栈有疑问.据我所知,函数中的前四个参数传递给Windows中的rcx,rdx,r8和r9寄存器(以及浮点数的xmm0-xmm3).所以带有四个参数的简单加法函数如下所示:

add:
   mov r10, rcx
   add r10, rdx
   add r10, r8
   add r10, r9
   mov rax, r10
   ret
Run Code Online (Sandbox Code Playgroud)

但是,我遇到的文档提到了这一点:

每个函数至少必须在堆栈上保留32个字节(4个64位值).该空间允许将传递到函数中的寄存器轻松复制到众所周知的堆栈位置.不需要被调用函数将输入寄存器参数溢出到堆栈,但堆栈空间预留确保它可以在需要时使用.

所以,我必须预留堆栈空间,即使我做的功能需要四个参数或更低,或者是它只是一个建议?

Pas*_*uoq 13

您的引用来自文档的"调用约定"部分.至少,如果不从汇编代码中调用其他函数,则不必担心这一点.如果你这样做,那么除了其他方面,你必须尊重"红区"和堆栈对齐方面的考虑因素,你引用的建议是为了确保.

编辑:这篇文章阐明了"红区"和"影子空间"之间的区别.

  • UN*X x86_64 ABI 提到的_red zone_ 是紧邻堆栈指针当前值下方的128 字节堆栈空间(即传统上被认为是堆栈的_未使用_ 部分的区域)。将执行重定向到信号处理程序时,异步事件(UN*X 信号)不得覆盖这些事件。效果是 `-128(%rsp) ... (%rsp)` 之间的空间被分配给当前正在执行的函数,您“自动”获得 128 字节的堆栈。对于经常调用的小函数,保存一些指令来设置/拆除堆栈帧会带来显着的好处。 (2认同)