Based on this Stack Overflow answer and this Stack Exchange answer

Just like cmp and jl, the call and 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? Its mentioned from time to time that call and 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.