So I'm currently reading Practical reverse engineering_ x86, x64, ARM, Windows Kernel, reversing tools, and obfuscation the book includes the following example to explain the stack frame.
addme(x, y)
01: 004113A0 55 push ebp
02: 004113A1 8B EC mov ebp, esp
03: ...
04: 004113BE 0F BF 45 08 movsx eax, word ptr [ebp+8]
05: 004113C2 0F BF 4D 0C movsx ecx, word ptr [ebp+0Ch]
06: 004113C6 03 C1 add eax, ecx
07: ...
08: 004113CB 8B E5 mov esp, ebp
09: 004113CD 5D pop ebp
10: 004113CE C3 retn
Function call
01: 004129F3 50 push eax ;param2
02: ...
03: 004129F8 51 push ecx ;param1
04: 004129F9 E8 F1 E7 FF FF call addme
05: 004129FE 83 C4 08 add esp, 8
I understand that on line 10 in the addme function we do mov ebp, esp to start a new stack frame for the current function, but what I dont understand is why we are calling mov esp, ebp right before the pop. If I understand correctly this is the current state of the stack before the call to mov esp, ebp is made.
TOP
**************************
* param2 *
**************************
* param1 *
**************************
* return addrs *
**************************
* old edp *
**************************
esp and edp are pointing after odl edp.
So why was the call to mov esp, ebp made?
If there is something wrong with the way I asked the question please let me know. Thank you.
esp
has not been modified. Otherwise its purpose would be to free the locals. Note that standard stack frame is not mandatory and frequently not used in optimized code. – Jesterpop %ebp
instead of doing aleave
in that case. (And in fact GCC does do that optimization even in debug mode). I'm assuming there's notsub esp, 1234
orpush
/call
(leaving stuff on the stack for the epilogue to clean up) inside the part not shown. – Peter Cordes