-1

我有以下汇编程序:

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

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

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

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

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

4

1 回答 1

1

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

您正在转储 RBP 指向的内存,而不是打印 RBP 的值。(使用p /x $rbp. 或使用 GDB 的 TUI 模式。有关GDB 提示,请参阅https://stackoverflow.com/tags/x86/infolayout reg的底部)。

call推送返回地址时内存会发生变化。例如,您没有为本地变量保留任何空间sub $8, %rsp,因此 RSP = RBP 并且 RSP 下面的空间是push写入call的位置。

这就是为什么非叶函数不能将红色区域(低于 RSP)用于其本地变量的原因。

于 2020-08-12T04:58:44.803 回答