It all depends on the conditional call, of course, but this usually happens.
The stack pointer can be moved randomly based on the fact that you need to click on or exit the stack at any given time. This can happen at any time inside the function, since you need to temporarily save some data on the stack.
The base pointer is usually set equal to the value for any given stack depth and is used to access the passed parameters (on the one hand) and local variables (on the other hand). It is also used to quickly move the stack pointer after exiting a function.
The reason this is done is to simplify the code so that you do not have to refer to the contents of the stack based on a possibly changing stack pointer. Using a base pointer greatly facilitates the task of generating code (you do not need to know that the stack pointer at any given time, just use a base pointer that remains unchanged throughout the function).
Without this, code that would like to press two copies of a local variable to call the following function would look like this:
mov eax, [esp+16] ; get var1 push eax ; push it mov eax, [esp+20] ; get var1 again push eax call _somethingElse
Put aside the fact that in this case you do not restart eax , the point I'm trying to make is that the relative position of the elements from the pointer of the moving stack can uselessly complicate matters.
For example, here is the function encoded in the assembly that follows the general calling convention:
_doSomething: push ebp ; stack current base pointer mov ebp, esp ; save previous stack pointer sub esp, 48 ; incl 48 bytes local storage ; do whatever you want here, including changing ; esp, as long as it ends where it started. mov esp, ebp ; restore previous stack pointer pop ebp ; and previous base pointer ret ; then return _callIt: mov eax, 7 push eax ; push parameter for function call _doSomething add esp, 4 ; get rid of pushed value :
If you follow this code, you can see that the ebp inside the function body is a fixed reference point with [ebp] ( ebp content) being the return address, [ebp+4] is the pressed value of 7 and [ebp-N] is the local storage for _doSomething , where N varies from 1 to 48 .
This is the case, regardless of how many elements are pressed or pushed inside the function body.