C++ 当您从函数返回结构时,汇编中实际发生了什么?

标签 c++ assembly x86-64 calling-convention abi

我试图弄清楚如果您从函数中按值返回结构,而不是返回指向该结构的指针,C++ 中实际发生了什么。如果一个函数只能返回一个可以放入寄存器的值,那么结构在按值发送时如何通信? (我在某处读过。)
我尝试在 Godbolt 上对其进行测试,看看它在做什么。但我不了解 assembly ,所以这对我来说有点乐观。
在没有太多汇编知识的情况下,在我看来,该函数只是在更改调用该函数之前存在的一些内存?那么return的概念从函数中获取某些内容只是一种抽象,该函数只是在已经存在的内存位置设置一些字节,然后结束跳回 main() ?在这种情况下,根本不会复制任何内容,并且返回是
“自由”?
Godbolt: Return int
Godbolt: Return struct{int int int}

最佳答案

How is a struct communicated when its sent by value if a function can only return a value that can fit in a register?


一个函数可以返回任何合法返回的东西。然而,只有寄存器大小或更小的值可以用于实现 return出于显而易见的原因,按照惯例将值留在单个寄存器中的声明。一些实现允许使用多个寄存器来表示大数据类型;当然,这意味着必须编写调用者以期望检查多个寄存器以获得完整的返回值。
机器级别的“会发生什么”不是语言标准规定的,而是取决于特定的编译器、它的优化能力、架构的细节等。但是,在普通平台上的直接实现是让调用者保留空间堆栈(以便它持续到清理之后)并让被调用者在那里写入数据。由于分配是静态的,因此在计算调用者的堆栈帧大小时,通常可以简单地考虑所需的空间。该实现可能会默默地生成一个指针并将其传递给寄存器中的被调用者;或者它可能会安排每个调用者将此保留空间放在其堆栈帧中的相同位置,以便被调用者可以向堆栈指针添加偏移量以确定写入位置;或者它可能会做一些我目前还没有足够创意的事情。
有许多方法可以在机器级别处理函数之间的信息通信,具体取决于机器和语言(尽管在进行这些讨论时我们通常谈论 C 或 C++,因为所有其他流行的选择要么在虚拟机上运行,​​被解释或有其他一些奇特的事情发生)。您要研究的通用术语是应用程序二进制接口(interface)或 ABI。

关于C++ 当您从函数返回结构时,汇编中实际发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67107603/

相关文章:

c++ - 发送一些消息后提升 asio 套接字退出

c++ - 过度渴望使用constexpr进行C++ union 零初始化

linux - 从 x86 中的特定位置读取文件

c++ - 如果一个对象在本地创建并在 C++ 中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch block 中?

c - 缓冲区溢出中的 Unname 系统调用

c - 使用 GCC -march=i686 逆向工程 C 代码

assembly - 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

c++ - 为什么libeay32中SHA512函数的符号没有前导下划线?

c++ - fetch_add(0, memory_order_relaxed/release) 到 mfence + mov 的转换是否合法?

c++ - 大无符号整数 (C++)