SivaDotRender
SivaDotRender

Reputation: 1651

decrementing ESP during a function call

I disassembled a small program that asks the user for their name then outputs "Hello + [user's_name]"

This is the disassembled output:

Main function:

Main function

Say hello function:

Say hello function

I noticed that for the main() function, the ESP register is decremented by Ox10 and for the say_hello() function, the ESP register is decremented by Ox20. Why is this the case?

FYI: My processor is an 1.4 GHz Intel Core i5 and I'm running OSX

Original C code:

void say_hello (void);

int main (){

    printf("Enter your name\n");
    say_hello();
    return 0;
}

void say_hello (void) { 

    char name[5]; 
    gets(name); //this is a unsafe function to use. Results in stack overflow
    printf("Hello %s\n", name); 

}

Upvotes: 0

Views: 657

Answers (3)

Abhineet
Abhineet

Reputation: 5409

The stack is "implemented" by means of the stack pointer, which points into the stack segment. Every time something is pushed on the stack (by means of pushl, call, or a similar stack opcode), it is written to the address the stack pointer points to, and the stack pointer decremented (stack is growing downwards, i.e. smaller addresses). When you pop something off the stack (popl, ret), the stack pointer is incremented and the value read off the stack.

For different function calls, we reserve space for local variables in the stack, so we decrement it and get the space. This is usually done using prologue and epilogue.

Prologue

A function prologue typically does the following actions if the architecture has a base pointer (also known as frame pointer) and a stack pointer (the following actions may not be applicable to those architectures that are missing a base pointer or stack pointer) :

  • Pushes the old base pointer onto the stack, such that it can be restored later (by getting the new base pointer value which is set in the next step and is always pointed to this location).
  • Assigns the value of stack pointer (which is pointed to the saved base pointer and the top of the old stack frame) into base pointer such that a new stack frame will be created on top of the old stack frame (i.e. the top of the old stack frame will become the base of the new stack frame).
  • Moves the stack pointer further by decreasing or increasing its value, depending on whether the stack grows down or up. On x86, the stack pointer is decreased to make room for variables (i.e. the function's local variables).

Epilogue

Function epilogue reverses the actions of the function prologue and returns control to the calling function. It typically does the following actions (this procedure may differ from one architecture to another):

  • Replaces the stack pointer with the current base (or frame) pointer, so the stack pointer is restored to its value before the prologue
  • Pops the base pointer off the stack, so it is restored to its value before the prologue
  • Returns to the calling function, by popping the previous frame's program counter off the stack and jumping to it

Upvotes: 2

Dan Byström
Dan Byström

Reputation: 9244

It allocates space on the stack for local variables. First BP it set to the current value of SP, then SP is decremented to make room for the local variables used by the function. As you can see, later [ss:rbp+???] is used to access parts of memory of this reserved space.

This is basically the same as PUSHing some dummy value a repeated number of times onto the stack.

Before the function leaves, it is crucial that the exact amount is added back to SP, otherwise a wrong return address will be used by the RET instruction, and the program will most likely crash.

Upvotes: 3

icbytes
icbytes

Reputation: 1851

As far as I rememeber, such decrements are mostly used to "reserve" place on stack or to guarantee even memory alignment.

What does it mean to align the stack?

Upvotes: 0

Related Questions