Search code examples
assemblygdbx86-64attred-zone

Value of rbp changing after jumping into a new function


I have the following assembly program:

.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

When stepping through the program, after the call func but before the push %rbp when trying access the value of rbp, which was previously $0x0800001e` (8 byte, 0 byte, 0 byte, 30 byte), it now shows all zeros:

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

Why does this occur? Does rbp reset its value (though keeping its address) between function calls?


Solution

  • The value of RBP doesn't change. Each asm instruction only changes the architectural state of the machine (register + memory contents) in the ways documented in the manual. (Intel and AMD both publish PDF manuals; HTML extract of the instruction-set reference from IInel's PDF at https://www.felixcloutier.com/x86/)

    You're dumping memory pointed-to by RBP, not printing the value of RBP. (Do that with p /x $rbp. Or use GDB's TUI mode with layout reg. See the bottom of https://stackoverflow.com/tags/x86/info for GDB tips).

    The memory changes when call pushes a return address. You didn't reserve any space for your local vars with sub $8, %rsp for example, so RSP = RBP and the space below RSP is where push and call write.

    That's why non-leaf functions can't use the red-zone (below RSP) for their local vars.