ret instructions accomplish many tasks using a single instruction so it’s a bit hard to see what they are doing (if you don’t know about it already). If you take a look at the cdecl calling convention for Intel x86, it says just that a new function will first push the content of ebp onto the stack and pop it back to ebp when it’s done to restore it, like
But what about eip? It’s mentioned from time to time that
ret will handle eip automatically and eip will just jump around accordingly, but how? According to what is mentioned in the two pages I have listed above, as it turns out, the caller’s stack frame should instead be like
Just like what’s mentioned here (p. 5), here, and here (p. 16), the
call instruction will push eip onto the stack before it jumps elsewhere and the
ret will simply do a
pop eip. And that also explains why functions (when the stack grows downwards) will usually fetch
4(%esp) (instead of
(%esp)) for its first argument.
Related details can also be found from this page.