gpt4 book ai didi

c++ - 为什么这个函数将 RAX 插入堆栈作为第一个操作?

转载 作者:IT老高 更新时间:2023-10-28 21:46:39 25 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()> 的尾声用于比较的包装器:

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

琐碎:

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

最佳答案

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

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

(在 call 之前而不是之后要求对齐的 ABI 设计选择具有较小的优势,即如果在堆栈上传递了任何 args,此选择会使第一个 arg 与 16B 对齐。)

推送一个无关值效果很好,并且比CPUs with a stack engine 上的sub rsp, 8高效. (见评论)。

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

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