linux中寄存器的作用是什么,c-x86_64汇编器中RBP寄存器的作用是什么?

Linux使用x86-64(AMD64)架构的System V ABI; 有关详细信息,请参见OSDev Wiki上的System V ABI。

这意味着堆栈变小。 较小的地址在堆栈中“较高”。 典型的C函数被编译为

pushq %rbp ; Save address of previous stack frame

movq %rsp, %rbp ; Address of current stack frame

subq $16, %rsp ; Reserve 16 bytes for local variables

; ... function ...

movq %rbp, %rsp ; \ equivalent to the

popq %rbp ; / 'leave' instruction

ret

为局部变量保留的内存量始终是16个字节的倍数,以使堆栈对齐到16个字节。 如果局部变量不需要堆栈空间,则没有2982409126032180180224或类似指令。

(请注意,返回地址和前一个2982409126048957957440都被压入堆栈,大小均为8个字节,共16个字节。)

%rsp指向当前堆栈框架,而%rsp指向堆栈顶部。 由于编译器在函数内的任何点都知道rep ret和ret之间的区别,因此可以随意使用其中任何一个作为局部变量的基础。

堆栈框架只是本地函数的游乐场:当前函数使用的堆栈区域。

每当使用优化时,当前版本的GCC都会禁用堆栈框架。 这是有道理的,因为对于用C编写的程序,堆栈帧对于调试最有用,而其他方面则没什么用。 (不过,您可以使用2982409126048048957440保持堆栈帧,同时启用其他优化功能。)

尽管相同的ABI应用于所有二进制文件,但是无论它们以何种语言编写,某些其他语言的确需要使用堆栈框架来“展开”(例如,向当前函数的祖先调用者“抛出异常”); 即“展开”堆栈帧,可以中止一个或多个功能并将控制权传递给某些祖先功能,而无需在堆栈上保留不必要的内容。

当省略堆栈帧时-对于GCC为%rsp-函数实现本质上将更改为

subq $8, %rsp ; Re-align stack frame, and

; reserve memory for local variables

; ... function ...

addq $8, %rsp

ret

因为没有堆栈帧(%rsp用于其他目的,并且其值从不被压入堆栈),所以每个函数调用仅将返回地址压入堆栈,这是一个8字节的数量,因此我们需要减去8 从%rsp保留为16的倍数。(通常,从rep ret减去并加到rep ret的值是8的奇数倍。)

函数参数通常在寄存器中传递。 有关详细信息,请参见此答案开头的ABI链接,但总而言之,整数类型和指针在寄存器%rsp、%rsp、rep ret、ret、rep和ret中传递,而2982409126048957957446至2982409126048447中带有浮点参数。

在某些情况下,您会看到%rsp而不是%rsp。不要混淆:rep ret的含义与ret完全相同。 尽管通常将2982409126048957957444前缀与字符串指令(重复的指令)一起使用,但将其应用于ret指令时却没有任何作用。 只是某些AMD处理器的分支预测变量不喜欢跳转到ret指令,建议的解决方法是在该处使用rep ret。

最后,我忽略了堆栈顶部上方的红色区域(地址小于2982409126048957957440的128个字节)。 这是因为它对于典型功能并不是真正有用:在正常的had-stack-frame情况下,您希望将本地内容放在堆栈框架中,以使调试成为可能。 在省略堆栈框架的情况下,堆栈对齐要求已经意味着我们需要从2982409126048957957441中减去8,因此在该减法中包括局部变量所需的内存不会花费任何成本。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值