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?
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 withlayout reg. See the bottom of https://stackoverflow.com/tags/x86/info for GDB tips).The memory changes when
callpushes a return address. You didn't reserve any space for your local vars withsub $8, %rspfor example, so RSP = RBP and the space below RSP is wherepushandcallwrite.That's why non-leaf functions can't use the red-zone (below RSP) for their local vars.