提问人:alessio solari 提问时间:8/28/2023 最后编辑:Peter Cordesalessio solari 更新时间:8/29/2023 访问量:71
Ubuntu 上的 System V ABI 是否将返回地址放在调用方函数的框架内或被调用方函数的框架内?
Does the System V ABI on Ubuntu place the return address within the caller function's frame or the callee function's frame?
问:
我的系统:Ubuntu 22.04.3 在 x86_64上运行。GCC 版本 11.4.0
我之所以问这个问题,是因为就返回地址所在的帧(调用方或被调用方)而言,似乎有两种不同的表示形式。
这就是“计算机系统,程序员的视角”所展示的:
这就是“System V Application Binary Interface AMD64 Architecture Processor Supplement”所显示的内容:
正如您在System V ABI文档表示中看到的,我们在当前帧(called/callee函数)中具有返回地址,但是在book表示中,它在调用者帧(caller函数)中。
这是我的问题:
什么表述是正确的?
在特定帧(调用方或被调用方)内并置返回地址是否只是一件任意的愚蠢事情,并且没有被任何 ABI 指定?
答:
3赞
Erik Eidt
8/29/2023
#1
返回地址由调用方推送,但在函数完成并返回给调用方时由被调用方弹出,因此堆栈上的返回地址仅在被调用方激活期间存在。
因为当被调用方返回时,该返回地址被删除,并且调用方看不到或使用它,我认为它不是调用方堆栈帧的一部分。因此,我必须将其视为被调用方框架的一部分
正如其他人所说,这只是语义。重要的是操作(例如,谁弹出)和值(地址指向的位置)。
但是,一般来说,要回答某些东西属于哪个框架的问题,我会问:该存储持续多长时间以及谁将其从堆栈中弹出(即谁真正负责该存储)?
当被调用方返回时,堆栈上剩余的内容属于调用方。
评论
1赞
500 - Internal Server Error
8/29/2023
我同意。这是语义上的,但我认为你不能争辩说被调用方删除的东西属于调用方的堆栈框架。
1赞
Peter Cordes
8/29/2023
@500-InternalServerError :我同意。还有堆栈参数:被调用者“拥有”它们,即可以用不同的值覆盖它们。(GCC 通常不会这样做,但会进行尾部调用。你可以说调用方在指令点将堆栈参数交给被调用方。在 caller-pops 约定中,被叫方交还空格,但不交还值。(无论如何,这是我对语义的最初看法。退货地址更简单;在从调用方跳转的指令之前,它不存在于堆栈上,因此任何调用方代码都无法引用它。call
0赞
Peter Cordes
8/29/2023
即使在具有红色区域的调用约定(如 x86-64 System V)中,调用方也不能假定 upon return 是他们推送的返回地址。一个低效的函数可能会把它弹出到寄存器中,在那里存储其他东西,然后用来返回。ABI 并没有禁止这样做,就像被调用者拥有堆栈参数一样。因此,调用方在ABI保证持有返回地址的情况下,永远不会拥有该堆栈槽的任何所有权。[rsp-8]
jmp reg
评论