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

In assembly function prologue, isn't push rbp already moves its value to rsp ? Why did mov rbp, rsp instruction move the same rsp values to rbp again? Is it necessary or redundant?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
idep
  • 1
  • 1
  • 2
  • 2
    That is not what `push` does. Read its description again. It moves the value from `rbp` to the **memory location** which `rsp` points to (after being decremented by 8). – Nate Eldredge May 08 '21 at 16:53
  • `push rbp` decrements `rsp` by 8 and then writes the *prior* value of `rbp` to the *memory pointed to by `rsp`*. `mov rbp, rsp` then loads the new `rsp` value into the `rbp` register. – ecm May 08 '21 at 17:00

2 Answers2

5

isn't push rbp already moves its value to rsp?

No. push rbp is equivalent to:

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

No more, no less, just like pushing any other register (https://www.felixcloutier.com/x86/push). This stores rbp to memory pointed-to by rsp, but doesn't modify registers other than rsp-=8. It's not an enter instruction.


You may already know this, but rbp is used as a frame pointer. mov rbp, rsp saves the previous top of the stack to rbp, and this top now serves as the bottom of the current stack frame.

But this creates an issue: if rbp has been modified, what about the previous stack frame? Since the stack frame has been modified, after this function returns, rbp would be in the wrong position and things would go very wrong.

This is where push rbp comes in. It saves the value of rbp before being modified so that right before the function returns, rbp's original value can be popped right back to rbp so the previous stack frame remains okay.

(Or in other words, rbp is call-preserved, so we need to save/restore it as part of setting it up as a frame pointer for our stack frame.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
mediocrevegetable1
  • 4,086
  • 1
  • 11
  • 33
1

mov rbp, rsp takes the current value in rsp and moves it into rbp.

Think as: You want to save the last stackframe and build another one.

There is also a difference between intel (the code above) and at&t syntax.

Intel: mov dest, source

bplinux
  • 23
  • 3
  • 3
    These things are all true, but the phrasing of the question makes it clear they do know what `mov rbp, rsp` does. They're confused about the `push`. – Peter Cordes May 08 '21 at 18:06