当前位置: 首页 > 知识库问答 >
问题:

C 当你从函数返回一个结构时,在汇编中实际发生了什么?

王宏扬
2023-03-14

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

我试着在戈德博尔特上测试它,看看它在做什么。但我不理解大会,所以我有点乐观。

在我看来,在没有太多汇编知识的情况下,函数只是在调用函数之前改变了一些存在的内存?那么返回从函数中读取某些东西的概念只是一种抽象,函数只是在已经存在的内存位置设置一些字节,然后结束跳转回main()?在这种情况下,什么都不被复制,返回是“免费的”?

戈德博尔特:返回国际

Godbolt: Return struct{int int int}

共有2个答案

陆俭
2023-03-14

所以我花了几个小时玩戈德博尔特的编译器浏览器,一直读到我找到了实用的答案。

我收集的是这样的:

  1. 如果该值适合寄存器,则将其保留作为返回值保留在寄存器中。
  2. 如果该值适合 2 个寄存器,则将其保留在 2 个寄存器中。
  3. 如果该值大于此值,则调用方在其自己的堆栈中保留内存,并且函数直接写入调用方的堆栈。

都是G

慕河
2023-03-14

如果一个函数只能返回一个寄存器能容纳的值,那么当它通过值发送时,结构是如何通信的?

函数可以返回任何合法返回的内容。然而,由于显而易见的原因,按照将值留在单个寄存器中的惯例,只有寄存器大小或更小的值才能用于实现< code>return语句。一些实现允许使用多个寄存器来表示大型数据类型;当然,这意味着必须编写调用者来检查多个寄存器以获得完整的返回值。

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

根据机器和语言的不同,在机器级处理函数间信息通信的方法有很多种(尽管我们在讨论这些问题时通常会讨论C或C,因为所有其他流行的选择要么在VM上运行,要么被解释,要么有其他花哨的事情发生)。您要研究的一般术语是应用程序二进制接口(Application Binary Interface,简称ABI)。

 类似资料:
  • 在 C 中,当一个应该返回对象的函数在没有 return 语句的情况下结束时会发生什么?会得到什么回报? 例如。

  • 我对反应性API比较陌生,很好奇当我们从web控制器返回流量时,幕后发生了什么。 根据spring-web文档 反应性返回值的处理如下: 与使用DeferreDreSult类似,适用于单值promise。例子包括单(反应器)或单(RxJava)。 因此,例外是两个API的行为应该与多值流(Flux)的行为应该与返回deferredresult的行为相似。 但是在返回延迟结果的API中,整个列表在浏

  • 问题内容: Go函数和方法可以返回多个值。 总和,prod:= learningMultiple(10,50) 它类似于返回元组吗? 我来自红宝石土地,我可以返回一个数组和一个 问题答案: 我们可以轻松地查看一些已编译的代码,以确认幕后情况。 考虑以下代码段: 如果我们反汇编所创建的ELF二进制文件,您将看到类似以下内容(内联被禁用,因此我们可以看到正在发生的调用): 因此,只需将结果字节放入堆栈

  • 本文向大家介绍当C#中的结果为空时,LINQ返回什么?,包括了当C#中的结果为空时,LINQ返回什么?的使用技巧和注意事项,需要的朋友参考一下 语言集成查询(LINQ)是基于直接将查询功能集成到C#语言中的一组技术的名称。 您可以在C#中为SQL Server数据库,XML文档,ADO.NET数据集以及支持IEnumerable或通用IEnumerable <T>接口的任何对象集合编写LINQ查询

  • 问题内容: 我正在创建一个需要实施的游戏。在游戏过程中,我想在特定时间内暂停监听器。我尝试从方法返回false ,但方法仍然保持执行状态。还有其他方法可以让监听器暂停一段时间吗?任何人都请解释一下从错误返回的实际含义是什么? 问题答案: 从View文档中: 如果您返回,则告诉android媒体已经处理完毕。算了吧。 如果您返回,则基本上会说“不是我的问题,请其他人来处理此点击”。然后android

  • 问题内容: 如果我在构造函数中返回一些值或对象,那么var会得到什么? 在两种情况下都会得到什么n? 其实这是一个测验问题,答案是什么? 自定义对象构造函数返回什么? a)新实例化的对象 b)未定义-构造函数不返回值 c)不论return语句是 d)等于return语句是什么;新实例化的对象(如果没有return语句) 问题答案: 我发现了这个很棒的链接: 上面提到的第二点魔术是构造函数返回特定的