gpt4 book ai didi

c++ - 为什么这个函数会把RAX压栈作为第一个操作呢?

转载 作者:太空宇宙 更新时间:2023-11-04 00:02:01 24 4
gpt4 key购买 nike

在下面的 C++ 源程序集中。为什么 RAX 会被压入栈?

RAX,据我所知,ABI 可以包含来自调用函数的任何内容。但是我们将它保存在这里,然后将堆栈向后移动 8 个字节。所以堆栈上的 RAX,我认为只与 std::__throw_bad_function_call() 有关手术 ... ?

代码:-

#include <functional> 

void f(std::function<void()> a)
{
a();
}

输出,来自 gcc.godbolt.org ,使用 Clang 3.7.1 -O3:

f(std::function<void ()>):                  # @f(std::function<void ()>)
push rax
cmp qword ptr [rdi + 16], 0
je .LBB0_1
add rsp, 8
jmp qword ptr [rdi + 24] # TAILCALL
.LBB0_1:
call std::__throw_bad_function_call()

我确信原因很明显,但我正在努力弄清楚。

这是一个没有std::function<void()> 的tailcall用于比较的包装器:

void g(void(*a)())
{
a();
}

琐碎的:

g(void (*)()):             # @g(void (*)())
jmp rdi # TAILCALL

最佳答案

64-bit ABI要求堆栈在 call 指令之前对齐到 16 字节。

call 将一个 8 字节的返回地址压入堆栈,这会破坏对齐,因此编译器需要在下一个 之前再次将堆栈对齐为 16 的倍数调用

(ABI 设计选择在 调用 之前而不是之后要求对齐,这有一个小优势,即如果在堆栈上传递了任何参数,这个选择会使第一个 arg 16B 对齐。)

推送无关值效果很好,并且可以sub rsp, 8 on CPUs with a stack engine 更有效率. (查看评论)。

关于c++ - 为什么这个函数会把RAX压栈作为第一个操作呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39360897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com