首页 >后端开发 >C++ >为什么在使用 std::function 进行尾调用期间将 RAX 寄存器压入堆栈?

为什么在使用 std::function 进行尾调用期间将 RAX 寄存器压入堆栈?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-12 19:07:10312浏览

Why is the RAX Register Pushed onto the Stack During Tail Calls with std::function?

尾调用情况下的堆栈对齐

问题是为什么在生成的汇编代码中首先将 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn