跳入新函数后 rbp 的值发生变化

Value of rbp changing after jumping into a new function

我有以下汇编程序:

.globl main
main:
    push %rbp
    mov %rsp, %rbp
    movb , -1(%rbp)
    movw , -4(%rbp)
    mov -1(%rbp), %rax
    add -4(%rbp), %rax
    call func
    pop %rbp
    ret

func:
    push %rbp
    mov %rsp, %rbp
    movl , -4(%rbp)
    mov -4(%rbp), %rbx
    pop %rbp
    ret

当单步执行程序时,在 call func 之后但在 push %rbp 之前尝试访问 rbp 的值时,它之前是 $0x0800001e`(8 字节,0 字节, 0 字节, 30 字节), 它现在显示全零:

>>> x/1xw $rbp-4
0x7fffffffe410: 0x00000000

为什么会出现这种情况? rbp 是否在函数调用之间重置其值(尽管保留其地址)?

RBP 的值不变。每个 asm 指令仅以手册中记录的方式更改机器的体系结构状态(寄存器 + 内存内容)。 (英特尔和 AMD 都发布了 PDF 手册;HTML instruction-set 参考摘自 Iinel 在 https://www.felixcloutier.com/x86/ 的 PDF)

您正在通过 RBP 转储内存 pointed-to,而不是打印 RBP 的值。 (使用 p /x $rbp 执行此操作。或者使用 layout reg 的 GDB 的 TUI 模式。请参阅 https://whosebug.com/tags/x86/info 的底部以获取 GDB 提示)。

call 压入一个return 地址 时内存发生变化。例如,您没有使用 sub , %rsp 为本地变量保留任何 space,因此 RSP = RBP 和 RSP 下面的 space 是 pushcall写。

这就是为什么 non-leaf 函数不能将 red-zone(低于 RSP)用于其局部变量。