I'm reading a book that explains how the ebp and eip registers work when a function is called. The following figure is provided:
here array is a local function variable. The function arguments are a, and b. This is how the actual C code looks like:
#include <stdio.h>
void function(int a, int b)
{
int array[8];
}
int main()
{
function(1,2);
return 0;
}
I compile with gcc -m32 -g function.c and run the program in gdb. The command disas main shows (skipped some lines):
0x08048474 : push $0x2 0x08048476 : push $0x1 0x08048478 : call 0x804843b 0x0804847d : add $0x10,%esp
the first and last few instructions of function() are:
0x0804843b : push %ebp
0x0804843c : mov %esp,%ebp
0x0804843e : sub $0x38,%esp
0x08048441 : mov %gs:0x14,%eax
0x08048447 : mov %eax,-0xc(%ebp)
0x0804844a : xor %eax,%eax
0x0804844c : nop
...
0x0804845e : leave
0x0804845f : ret
and when I inspect the contents of ebp:
(gdb) x/4xw $ebp 0xffffcd48: 0xffffcd68 0x0804847d 0x00000001 0x00000002
I understand that in the stack, ebp should be followed by the return location 0x0804847d and the function arguments 0x00000001 and 0x00000002. However I don't know what is 0xffffcd68. Is this the address of ebp?
It is the value of ebp at the beginning of the function.
It's a consequence of push %ebp and the fact that the x86 stack is Full Descending.
It's the caller frame pointer.
Beware that the compilers update the way they handle the stack much more frequently than books authors do with their books.
Particularly: alignment, frame-pointer omission, RVO, implicit parameters and so on may throw you off.
User contributions licensed under CC BY-SA 3.0