I'm reading about stack pointer and frame pointer on Wiki - Call stack.
(Section: Stack and frame pointers): ["] At function return, the stack pointer is instead restored to the frame pointer, the value of the stack pointer just before the function was called. Each stack frame contains a stack pointer to the top of the frame immediately below. [."]
The part I don't understand is that supposed that during a procedure call $fp
point to the address $sp
point to before the call, so after the call we know how to recover $sp
, but how about $fp
itself?
Here is my homemade graph about my problem (the stack in my graph is supposed to growing from high address to low address):
Usually, the frame pointer (or, usually and more correctly, previous frame pointer) is pushed on to the stack as well so is recoverable with a simple pop
instruction.
For example, here's a function in x86 with prolog and epilog (ebp
is the frame pointer):
push ebp ; push current frame pointer
mov ebp, esp ; set up frame pointer for this new frame
sub esp, <frameSize> ; allocate stack space (locals)
weave magic ; the meat of the function
mov esp, ebp ; deallocate stack space
pop ebp ; restore previous frame pointer
ret ; back to caller
In terms of what $fp
contained before making the immediate call, it will have been the frame pointers for the most recent call before that. And this continues all the way up the call stack, until you reach the top (or find yourself using a different calling convention).