首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >理解C/C++中函数调用的堆栈框架?

理解C/C++中函数调用的堆栈框架?
EN

Software Engineering用户
提问于 2013-04-18 16:58:15
回答 4查看 102.5K关注 0票数 25

我试图了解堆栈帧是如何构建的,哪些变量(params)被按什么顺序推到堆栈中?一些搜索结果表明,C/C++编译器是根据函数内执行的操作来决定的。例如,如果函数被认为只是将传入的int值增加1(类似于++操作符)并返回它,它将把函数和局部变量的所有参数放入寄存器中。

我想知道哪些寄存器用于返回或传递值参数。如何返回引用?编译器如何在eax、ebx、ecx和edx之间进行选择?

要理解在函数调用期间如何使用、构建和销毁寄存器、堆栈和堆引用,我需要了解什么?

EN

回答 4

Software Engineering用户

回答已采纳

发布于 2013-04-18 21:50:00

除了Dirk所说的,堆栈帧的一个重要用途是保存以前的寄存器值,以便在函数调用后恢复它们。因此,即使在寄存器用于传递参数、返回值和保存返回地址的处理器上,这些寄存器的值在函数调用之前也保存在堆栈中,以便在调用后可以恢复。这允许一个函数调用另一个函数,而不覆盖自己的参数或忘记自己的返回地址。

因此,在典型的“泛型”系统上从函数A调用函数B可能涉及以下步骤:

  • 函数A:
    • 推送返回值的空间
    • 推送参数
    • 推送回信地址

  • 跳转到函数B
  • 功能B:
    • 推送前一个堆栈帧的地址
    • 推送此函数使用的寄存器的值(以便可以还原它们)
    • 局部变量推送空间
    • 做必要的计算
    • 恢复寄存器
    • 还原前一个堆栈帧
    • 存储函数结果
    • 跳转到返回地址

  • 函数A:
    • 弹出参数
    • 弹出返回值

这绝不是函数调用能够工作的唯一方法(我可能有一两步不正常),但它应该让您了解如何使用堆栈来让处理器处理嵌套函数调用。

票数 15
EN

Software Engineering用户

发布于 2013-04-18 17:25:44

这取决于所使用的调用约定。不管是谁定义了调用约定,谁都可以做这个决定。

在x86上最常见的调用约定中,寄存器不用于传递参数;参数从最右边的参数开始推入堆栈。返回值放在eax中,如果需要额外的空间,可以使用edx。引用和指针都以eax中地址的形式返回。

票数 12
EN

Software Engineering用户

发布于 2016-10-18 11:05:26

如果您非常了解堆栈,那么您将了解内存在程序中是如何工作的,如果您了解内存在程序中是如何工作的,那么您将了解程序中的函数存储方式,如果您了解程序中的函数存储是如何工作的,那么您将了解递归函数是如何工作的,如果您了解递归函数是如何工作的,那么您将了解编译器是如何工作的,如果您了解编译器的工作方式,那么您将很容易地调试任何程序。

让我解释一下堆栈是如何工作的:

首先,您必须知道函数如何存储在堆栈中:

堆存储动态内存分配值。堆栈存储自动分配和删除值。

让我们用例子来理解:

代码语言:javascript
运行
复制
def hello(x):
    if x==1:
        return "op"
    else:
        u=1
        e=12
        s=hello(x-1)
        e+=1
        print(s)
        print(x)
        u+=1
    return e

hello(4)

现在了解本程序的部分内容:

现在让我们看看什么是堆栈,哪些是堆栈部件:

堆栈的分配:

记住一件事,如果任何函数得到“返回”,不管它加载了他的所有本地变量或任何东西,它将立即从堆栈返回,这将是他的堆栈框架。这意味着当任何递归函数得到基本条件后,我们在基条件之后加上返回,这样基条件就不会等待加载位于程序“one”部分的局部变量,它将立即从堆栈返回当前帧,如果一个帧返回下一个帧处于激活记录中。在实际中可以看到这一点:

取消区块分配:

因此,每当函数找到返回语句时,它都会从堆栈中删除当前帧。

当从堆栈返回时,值将以与它们在堆栈中分配的顺序相反的顺序返回。

这些都是非常简短的描述,如果您想更深入地了解堆栈和双递归,请阅读本博客的两篇文章:

更多关于一步一步的堆栈信息

更多关于带堆栈的逐步双递归的信息

票数 9
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/195385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档