尾调用情况下的堆栈对齐
问题是为什么在生成的汇编代码中首先将 RAX 寄存器压入堆栈与 std::function 对象交互的 C 代码。
必要性堆栈对齐
64 位 ABI 要求在任何调用指令之前堆栈必须对齐到 16 个字节。当进行调用时,它会将 8 字节返回地址压入堆栈,从而破坏这种对齐方式。为了纠正这个问题,编译器必须在后续调用之前采取措施将堆栈重新对齐为 16 的倍数。
推送一个一次性值进行对齐
而不是执行“sub rsp, 8”推动“无关”值,例如 RAX,事实证明在配备堆栈的 CPU 上效率更高 引擎。这是因为简单的推送指令通常需要比 sub rsp, 8 指令更少的处理器开销。
与没有 std::function Wrapper 的 Tailcall 比较
当有时不存在 std::function 包装器,如“void g(void (*a)())”示例中所示,尾部调用很简单:一个简单的跳转 (jmp)对目标函数的指令。堆栈对齐不需要额外的步骤,因为尾调用自然会保持正确的堆栈对齐。
以上是为什么在使用 std::function 进行尾调用期间将 RAX 寄存器压入堆栈?的详细内容。更多信息请关注PHP中文网其他相关文章!