Reputation: 1
EDIT The real question is at the end of the post I'm trying to undestand how gcc manage the stack size but I have some question I don't find the answer.
Gcc does something weird when I call a function in another one. It allocates extra bytes and I don't understand what for.
Here is the simpliest C code ever :
int f(){
int i =12;
return 0;
}
int main(void){
f();
return 0;
}
and then the disass of f() that gdb produces :
0x08048386 <+0>: push %ebp
0x08048387 <+1>: mov %esp,%ebp
0x08048389 <+3>: sub $0x10,%esp <- this part
0x0804838c <+6>: movl $0xc,-0x4(%ebp)
0x08048393 <+13>: mov $0x0,%eax
0x08048398 <+18>: leave
0x08048399 <+19>: ret
Here ok I undestand. gcc makes 16 bytes alignement stack as i is an int (so 4 bytes) gcc allocates 16 bytes on the stack for i.
But As soon as I call a function in f() I don't get what gcc is doing. Here is the new C code :
int g(int i){
i=12;
return i;
}
int f(){
int i =12;
g(i);
return 0;
}
int main(void){
f();
return 0;
}
And then the f() disass :
0x08048386 <+0>: push %ebp
0x08048387 <+1>: mov %esp,%ebp
0x08048389 <+3>: sub $0x14,%esp <- Here is my understanding
0x0804838c <+6>: movl $0xc,-0x4(%ebp)
0x08048393 <+13>: mov -0x4(%ebp),%eax
0x08048396 <+16>: mov %eax,(%esp)
0x08048399 <+19>: call 0x8048374 <g>
0x0804839e <+24>: mov $0x0,%eax
0x080483a3 <+29>: leave
0x080483a4 <+30>: ret
Then gcc allocates 4 extra bytes whereas there is no more change than f() is calling g().
And this can be worst when I play with more functions.
So any of you have any idea what are this extra bytes for and what is gcc's stack allocation policy ?
Thank you in advance.
EDIT: real question
Ok sorry I wrote the question too fast in fact it's ok with the sub 0x14 %esp my real understanding is with this piece of code :
int f(){
char i[5];
char j[5];
i[4]=0;
j[4]=0;
strcpy(i,j);
return 0;
}
int main(void){
f();
return 0;
}
And then f()'s disass :
0x080483a4 <+0>: push %ebp
0x080483a5 <+1>: mov %esp,%ebp
0x080483a7 <+3>: sub $0x28,%esp
0x080483aa <+6>: movb $0x0,-0x9(%ebp)
0x080483ae <+10>: movb $0x0,-0xe(%ebp)
0x080483b2 <+14>: lea -0x12(%ebp),%eax
0x080483b5 <+17>: mov %eax,0x4(%esp)
0x080483b9 <+21>: lea -0xd(%ebp),%eax
0x080483bc <+24>: mov %eax,(%esp)
0x080483bf <+27>: call 0x80482d8 <strcpy@plt>
0x080483c4 <+32>: mov $0x0,%eax
0x080483c9 <+37>: leave
0x080483ca <+38>: ret
The stack look like something like that :
[oldip][oldebp][Extra(8B)][Arrays(10B)][Rearrange stack(14B)][Argument1(4B)][Argument2(4B)]
Here we see that 8 extra bytes come between the saved ebp and the local variables. So here is really my understanding.
Sorry for having posting too fast and still thanks for your quick answer.
Upvotes: 0
Views: 902
Reputation: 71546
I would think in the first case the 4 bytes are for the one parameter needed when calling g(). and in the second case two 4 byte words needed for the two parameters when calling strcpy(). call a dummy function with three parameters and see if it changes to 12 bytes.
Upvotes: 0
Reputation: 8107
0x08048386 <+0>: push %ebp
0x08048387 <+1>: mov %esp,%ebp
0x08048389 <+3>: sub $0x14,%esp <- include 0x10 bytes for stack alignment and 4 byte for 1 parameter
0x0804838c <+6>: movl $0xc,-0x4(%ebp)
0x08048393 <+13>: mov -0x4(%ebp),%eax
0x08048396 <+16>: mov %eax,(%esp)
0x08048399 <+19>: call 0x8048374 <g>
0x0804839e <+24>: mov $0x0,%eax
0x080483a3 <+29>: leave
0x080483a4 <+30>: ret
as you can see, it allocate 16 bytes included i and stack alignment, plus 4 byte for one parameter, the stack will look like this.
00 7f 7c 13 --> return from call address
00 00 00 00 --> this one for parameter when call g(i) --> low address
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 0C ---> i (ignore about edian) --> high address
Upvotes: 0