首页 > 解决方案 > C++ 当您从函数返回结构时,汇编中实际发生了什么?

问题描述

我试图弄清楚如果您从函数中按值返回结构,而不是返回指向该结构的指针,C++ 中实际发生了什么。如果一个函数只能返回一个可以放入寄存器的值,那么结构在按值发送时如何通信?(我在某处读过。)

我尝试在 Godbolt 上对其进行测试,看看它在做什么。但我不了解大会,所以这对我来说有点乐观。

在没有太多汇编知识的情况下,在我看来,该函数只是在更改调用该函数之前存在的一些内存?那么return从函数中获取某些东西的概念只是一种抽象,函数只是在已经存在的内存位置设置一些字节,然后结束跳回到main()? 在这种情况下,根本没有复制任何东西并且返回是“免费的”?

Godbolt:返回整数

Godbolt:返回结构{int int}

标签: c++assemblyx86-64calling-conventionabi

解决方案


如果一个函数只能返回一个可以放入寄存器的值,那么结构在按值发送时如何通信?

一个函数可以返回任何合法返回的东西。但是,出于显而易见的原因,按照将值留在单个寄存器中的约定,只能使用寄存器大小或更小的值来实现return语句。一些实现允许使用多个寄存器来表示大数据类型;当然,这意味着必须编写调用者以期望检查多个寄存器以获得完整的返回值。

机器级别的“会发生什么”不是由语言标准规定的,而是取决于特定的编译器、它的优化能力、架构的细节等。但是,在普通程序上的直接实现平台是让调用者在堆栈上保留空间(以便它持续到清理之后)并让被调用者在那里写入数据。由于分配是静态的,因此在计算调用者的堆栈帧大小时,通常可以简单地考虑所需的空间。该实现可能会默默地生成一个指针并将其传递给寄存器中的被调用者;或者它可能会安排每个调用者将此保留空间放在其堆栈帧中的相同位置,以便被调用者可以向堆栈指针添加偏移量以确定写入位置;或者它可能会做一些我目前还没有足够创意的事情。

有许多方法可以在机器级别处理函数之间的信息通信,具体取决于机器和语言(尽管在进行这些讨论时我们通常谈论 C 或 C++,因为所有其他流行的选择要么在虚拟机上运行,​​被解释或有其他一些奇特的事情发生)。您要研究的通用术语是Application Binary Interface或 ABI。


推荐阅读