我试图了解堆栈帧是如何构建的以及哪些变量(参数)以什么顺序被推送到堆栈?
这取决于处理器的架构。但是,通常,堆栈从高地址向低地址增长(如果我们将内存地址视为数值)。一个堆栈帧是“这个函数放在堆栈上的任何东西”
放入堆栈的“东西”通常是:
- 将地址返回给调用函数。
- 一个帧指针,指向调用开始时的堆栈帧。
- 当此函数返回时,需要“保留”的已保存寄存器。
- 局部变量。
- 调用堆栈中“下一个”函数的参数。
C/C++ 的编译器根据函数内执行的操作来决定。例如,如果假设函数只是将传递的 int 参数的值增加 1 并返回(类似于 ++ 运算符),它将把所有 ... 函数的参数和函数内的局部变量放在寄存器中并执行加法....想知道哪个寄存器用于返回/按值传递?....如何返回引用?
编译器有关于如何传递参数的规则,对于常规函数调用[即不是“内联”函数],参数总是以相同的顺序传递,在寄存器和堆栈内存的相同组合中。如果不是这种情况,编译器在决定传递参数之前必须确切地知道函数做了什么。
不同的处理器架构有不同的规则。x86-32 通常有一个或两个用于输入参数的寄存器,并且通常有一个用于返回值的寄存器。x86-64 最多使用 5 个寄存器将前五个值传递给函数。任何进一步的参数都在寄存器中传递。
返回引用与返回任何其他值没有什么不同。值(在这种情况下是返回对象的地址)。在 x86-32 中,返回值在 EAX 中。在 x86-64 中,返回值在 RAX 中。在 ARM 中,R0 用于返回值。在 29K 中,R96 用于返回值。