我想知道哪个负责清理堆栈
假设你有一个 fun 函数,可以这样说:
var = fun(int x, int y, float z, char x);
什么时候fun
被调用,它将与参数一起进入堆栈,然后当函数返回时,负责清理堆栈的人是它自己的函数还是将保存返回值的“var”。
还有一件事,任何人都可以解释调用约定的概念吗?
我想知道哪个负责清理堆栈
假设你有一个 fun 函数,可以这样说:
var = fun(int x, int y, float z, char x);
什么时候fun
被调用,它将与参数一起进入堆栈,然后当函数返回时,负责清理堆栈的人是它自己的函数还是将保存返回值的“var”。
还有一件事,任何人都可以解释调用约定的概念吗?
您自己提到了答案:调用约定。
调用约定类似于合约。它决定以下事项:
根据平台和编程环境,有许多不同的调用约定。x86 平台上的两个常见调用约定是:
标准调用
参数从右到左传递到堆栈上。被调用的函数清理堆栈。
cdecl
参数从右到左传递到堆栈上。调用函数清理堆栈。
在这两种情况下,返回值都在EAX
寄存器中(或ST0
浮点值)
x86 平台的许多编程语言都允许指定调用约定,例如:
德尔福
function MyFunc(x: Integer): Integer; stdcall;
微软 C/C++
int __stdcall myFunc(int x)
一些使用说明:
创建一个简单的应用程序时,很少需要更改或了解调用约定,但有两种典型情况需要您关注调用约定:
有关更多详细信息,我推荐这些 Wikipedia 文章:
调用约定是指谁在清理堆栈;调用者或被调用者。
调用约定可能在以下方面有所不同:
- 参数和返回值的放置位置(在寄存器中;在调用堆栈上;两者的混合)
- 传递参数的顺序(或单个参数的一部分)
- 设置和清理函数调用的任务如何在调用者和被调用者之间分配。
- 被调用者可以直接使用的寄存器有时也可能包括在内
架构几乎总是有不止一种可能的调用约定。
到该行完成时,var 将保存 fun() 返回的值,并且 fun 使用的堆栈上的任何内存都将消失:“push”、“pop”都整齐。
调用约定:编译器组织的所有东西,以便 fun 可以完成它的工作。考虑这些参数 x、y、z。它们被压入堆栈的顺序是什么(实际上它们是通过堆栈传递的)?只要调用者和被调用者同意就没有关系!这是一个约定。