To further expand on perrors answer, you're looking at a function that preserves the stack frame, which is a nice little trick to simplify walking backwards through the call stack. When you initially push EBP
in the prologue, it subtracts pointer size (which is of course 0x4
in x86) before writing the old EBP
to the stack, as seen below in equivalent code.
SUB ESP, 0x4 ; Result from PUSH
MOV [ESP], EBP ; Save old EBP
MOV EBP, ESP ; Set new EBP
Now once it reaches the epilogue and restores the stack pointer (ESP
) from the frame pointer (EBP
) it's still 4 bytes below the original stack when entering the function. What's at the current stack pointer? It holds the previous frame pointer from before invoking the current function. By popping EBP
you are both restoring the frame pointer to what it was and fixing the stack at the same time, as shown below.
MOV ESP, EBP ; Restore ESP from prologue
MOV EBP, [ESP] ; Restore saved EBP
ADD ESP, 0x4 ; Result from POP
The return following this can be interpreted as a POP EIP
instruction, as shown below.
MOV EIP, [ESP] ; Redirect execution to return address
ADD ESP, 0x4 ; Result from pop
I should also add that CALL can be simplified as a push
/jump
, as shown below.
SUB ESP, 0x4 ; Result from PUSH
MOV [ESP], ReturnAddress ; Save next instruction as return address
JMP CallAddress ; Redirect execution to call address
As you can probably see, this allows you to simply work backwards to get both the frame pointer and return address from previous function calls that led to the current function. Hopefully that explains both the purpose and logic behind the frame pointer preservation your question is based on.
Note: In terms of the post by perror, I also wanted to point out a couple things. First the constant 0x4
should be sizeof(uintptr_t)
. I know your code is x86 so he's not wrong, it's just good to know. Second is that push can be thought of as subtracting the stack before setting the value, while pop can be thought of as the exact opposite, getting the value first before adding the stack.