Behaviour of EBP and ESP in stack during 2 function calls

I was going through the how the function calls work in x86 platform. As I understand following steps takes place when a function is called:

  • parameters and return address of the function are pushed on the stack.

  • then value of current EBP is pushed onto stack.

  • Now that ESP has changed( due to step 2 ), EBP is replaced with ESP and now they are pointing to same address of (Stack?).

  • Then the local variables are pushed and function do it's work.

  • Finally local variables of this function are poped and so are the registers. In this process ESP is also moving, right?

  • And at the end, EBP is replaced with value that is held at current ESP

  • Now ESP and EBP are pointing to same address of the stack.

  • So my question if all the above points are correct, otherwise please correct me, how will this system work in case of 2 function calls. Let me explain

  • for first function call, ebp is pushed to stack and esp and ebp are made same.

  • now esp is incremented to create a local stack of 1st function call, say foo().

  • now lets say there is a 2nd function call from foo(), say goo().

  • now again the same procedure will happen.... current ebp will be pushed to stack

  • esp and ebp will be made same and esp will be incremented ( technically, decremented ) for local variables of goo() function.

  • Now let's focus on when the functions will return.

  • returning from goo(), esp increment as the local registers are poped from stack and at last esp will be assigned the value which the location ebp holds not the value of current ebp, right?

  • then the location holding the ebp will be poped.

  • So my question is that if this is the case now we have lost the starting of the stack of the function foo() because ebp and esp points to ebp of foo(), which will be poped as soon as the foo() returns...

    As this is not what happens in practical, I must be missing something. Please help me...

    Thanks.


    I assume that you are talking about the cdecl (https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl) calling convention (the one often used in c).

    %ebp is the Base Pointer register, it is callee-saved which means the caller can assume that the callee will not modify its value, hence the caller can assume that %ebp will always refer to the base of its stack.

    %esp is the Stack Pointer register, it is also callee saved, but, since the caller pushed the arguments for the callee on the stack %esp was decremented, so it needs to be incremented when the callee return. And I think this is where your problem lurk, the value of %esp is only incremented enough to free the allocated arguments, not to return to the base of the stack.

    And %ebp and %esp effectively refer to the base and the 'top' of the stack. no problem

    链接地址: http://www.djcxy.com/p/80388.html

    上一篇: 函数调用如何在x86 32中工作?

    下一篇: 在两次函数调用期间,EBP和ESP在堆栈中的行为