函数序言中的“mov rbp, rsp”

问题描述

push   rbp
mov    rbp,rsp
mov    DWORD PTR [rbp-0x4],edi

在汇编函数序言中,不是 push rbp 已经将其值移动到 rsp 了吗?为什么 mov rbp,rsp 指令再次将相同的 rsp 值移动到 rbp?是必要的还是多余的?

解决方法

push rbp 不是已经将其值移动到 rsp 了吗?

没有。 push rbp 相当于:

sub rsp,8                 ; but without setting FLAGS
mov [rsp],rbp

不多也不少,就像推送任何其他寄存器 (https://www.felixcloutier.com/x86/push) 一样。这将 rbp 存储到 rsp 指向的内存中,但不会修改除 rsp-=8 之外的寄存器。这不是 enter instruction


您可能已经知道这一点,但 rbp 用作帧指针mov rbp,rsp 将前一个堆栈顶部保存到 rbp,这个顶部现在用作当前堆栈帧的底部。

但这会产生一个问题:如果 rbp 已被修改,那么之前的堆栈帧呢?由于栈帧被修改了,所以这个函数返回后,rbp会出现错误的位置,事情会变得很糟糕。

这就是 push rbp 的用武之地。它在修改之前保存 rbp 的值,以便在函数返回之前,rbp 的原始值可以立即弹出rbp 所以前一个堆栈帧保持正常。

(或者换句话说,rbp 是调用保留的,因此我们需要保存/恢复它,作为将其设置为堆栈帧的帧指针的一部分。)

,

mov rbp,rsp 将 rsp 中的当前值移入 rbp。

认为: 您想保存最后一个堆栈帧并构建另一个。

intel(上面的代码)和 at&t 语法之间也存在差异。

英特尔: mov dest,source