【问题标题】:Who is responsible for cleanup?谁负责清理?
【发布时间】:2009-09-22 07:02:04
【问题描述】:
我想知道哪个负责清理堆栈
假设你有一个函数 fun 让我们这样说:
var = fun(int x, int y, float z, char x);
当fun 将被调用时,它将与参数一起进入堆栈,然后当函数返回时,负责清理堆栈的人是它自己的函数还是将保存返回值的“var” .
还有一件事,谁能解释一下调用约定的概念?
【问题讨论】:
标签:
c
compiler-construction
system
callstack
【解决方案1】:
您自己参考了答案:调用约定。
调用约定类似于合同。它决定以下事情:
- 谁负责清理参数。
- 将参数传递给被调用函数的方式和顺序。
- 返回值的存储位置。
有许多不同的调用约定,具体取决于平台和编程环境。 x86 平台上两种常见的调用约定是:
标准调用
参数从右到左传入堆栈。 called 函数清理堆栈。
cdecl
参数从右到左传入堆栈。 调用函数清理堆栈。
在这两种情况下,返回值都在EAX 寄存器中(或ST0 用于浮点值)
x86 平台的许多编程语言都允许指定调用约定,例如:
德尔福
function MyFunc(x: Integer): Integer; stdcall;
微软 C/C++
int __stdcall myFunc(int x)
一些使用说明:
在创建一个简单的应用程序时,很少需要更改或了解调用约定,但有两种典型情况需要您关注调用约定:
- 调用外部库时,例如 Win32 API:您必须使用兼容的调用约定,否则堆栈可能会损坏。
- 创建内联汇编代码时:您必须知道在哪些寄存器中以及在堆栈中的哪个位置可以找到变量。
有关更多详细信息,我推荐以下 Wikipedia 文章:
【解决方案2】:
calling convention指谁在做堆栈的清理;调用者或被调用者。
调用约定可能在以下方面有所不同:
- 参数和返回值的放置位置(在寄存器中;在调用
堆;两者的混合)
- 参数传递的顺序(或单个参数的一部分)
参数)
- 如何划分设置和清理函数调用的任务
在调用者和被调用者之间。
- 哪些寄存器可以被调用者直接使用,有时也可以
被列入
架构几乎总是有更多
比一种可能的调用约定。
【解决方案3】:
到该行完成时,var 将保存 fun() 返回的值,并且 fun 使用的堆栈上的所有内存都将消失:“push”、“pop”全部整理。
调用约定:编译器为了让 fun 发挥作用而组织的一切。考虑这些参数 x、y、z。它们被压入堆栈的顺序是什么(实际上它们是通过堆栈传递的)?只要调用者和被调用者同意就没有关系!这是一个约定。