In the standard x86 standard convention, before calling a function, this parameter is first pushed onto the stack.
And call op means "push the next address onto the stack, then go to the function", so the return address is also on the stack.
This means that before push ebp stack looks like this:
... param2 param1 param0 return_address <- esp
After calling push ebp it becomes
... param2 param1 param0 return_address ebp <- esp
Finally, mov ebp, esp saves this esp to ebp , so you can reference the return address and all input parameters relative to ebp and free the stack for local use.
source share