Quaxton Hale
Quaxton Hale

Reputation: 2520

What happens to EBP when calling a function

This is the program:

#include <stdio.h>

void test_function(int a, int b, int c, int d){

    int flag;   
    flag = 31337;

}

int main(){

    test_function(1,2,3,4);
}

From GDB:

    Breakpoint 1, main () at stack_example.c:14
    14      test_function(1,2,3,4);
    (gdb) i r esp ebp eip
    esp            0xffffcf88   0xffffcf88
    ebp            0xffffcf98   0xffffcf98
    eip            0x8048402    0x8048402 <main+6>
    (gdb) cont
    Continuing.

    Breakpoint 2, test_function (a=1, b=2, c=3, d=4) at stack_example.c:8
    8       flag = 31337;
    (gdb) i r esp ebp eip
    esp            0xffffcf70   0xffffcf70
    ebp            0xffffcf80   0xffffcf80
    eip            0x80483f3    0x80483f3 <test_function+6>
    (gdb) 

Dump of assembler code for function test_function:
   0x080483ed <+0>: push   ebp
   x080483ee <+1>:  mov    ebp,esp
   0x080483f0 <+3>: sub    esp,0x10
=> 0x080483f3 <+6>: mov    DWORD PTR [ebp-0x4],0x7a69
   0x080483fa <+13>:    leave  
   0x080483fb <+14>:    ret    

From GDB, Why does EBP not have the same value as what ESP was in main()? Shouldn't mov ebp, esp make EBP == 0xffffcf88? I thought this sets EBP to what ESP is.

EDIT:

I think I may have answered my own question. Please correct me. ESP is moved when the return address and saved frame pointer are pushed onto the stack.

The ESP value was 0xffffcf88 before the two values(both 4 bytes) were pushed onto the stack. Afterwards, it's value is 0xffffcf88 - 0x8 == 0xffffcf80. This is what EBP's current value is. Then ESP -= 0x10.

How is the value of ESP modified? Is it something like mov ESP, ESP - 0x8 ?

Upvotes: 2

Views: 730

Answers (1)

dbrank0
dbrank0

Reputation: 9476

I hope I understand your question.

First, you are correct about new value of frame pointer. Here you need to know that "break test_function" actually stops gdb after the function prologue has been executed, so you are already past the point where ebp is explicitly stored to stack. See detailed explanation.

ESP is decreased by four for every push (or call). It's also decreased (some immediate value subtracted) by the amount of space required by the local variables, etc. Different "calling conventions" are being used on x86, so these details may vary a bit.

Some parts of this are also compiler specific. For example GCC by default keeps stack 4-word aligned on x86 (for one reason to keep SSE unit happy). See this SO thread.

BTW: frame pointer is actually redundant as long as compiler knows how to unwind stack from any point in function and it is typically omitted with optimized code.

Upvotes: 2

Related Questions