РЕДАКТИРОВАТЬ Настоящий вопрос в конце поста Я пытаюсь понять, как gcc управляет размером стека, но у меня есть вопрос, который я не нахожу.
Gcc делает что-то странное, когда я вызываю функцию в другой.Он выделяет дополнительные байты, и я не понимаю, для чего.
Вот самый простой код на C:
int f(){
int i =12;
return 0;
}
int main(void){
f();
return 0;
}
, а затем дисбаланс f (), который создает gdb:
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
Здесь хорошо, я понимаю.gcc делает 16-байтовый стек выравнивания, так как i является целым числом (то есть 4 байта) gcc выделяет 16 байтов в стеке для i.
Но как только я вызываю функцию в f (), я не получаю то, чтоGCC делает.Вот новый код C:
int g(int i){
i=12;
return i;
}
int f(){
int i =12;
g(i);
return 0;
}
int main(void){
f();
return 0;
}
А затем f () пропадает:
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
Затем gcc выделяет 4 дополнительных байта, тогда как изменений больше нет, чем f ()Вызов g ().
И это может быть хуже, когда я играю с большим количеством функций.
Итак, у кого-нибудь из вас есть идея, для чего нужны эти дополнительные байты и какова политика выделения стека в gcc?
Заранее спасибо.
РЕДАКТИРОВАТЬ: реальный вопрос
Хорошо, извините, я написал вопрос слишком быстро, на самом деле все в порядке с подпунктом 0x14%ESP Я действительно понимаю, с этим фрагментом кода:
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;
}
А затем 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
Стек выглядит примерно так:
[oldip] [oldebp] [Extra (8B)] [Arrays (10B)] [Перегруппировать стек (14B)] [Argument1 (4B)] [Argument2 (4B)]
Здесь мы видим, что 8дополнительные байты находятся между сохраненным ebp и локальными переменными.Итак, вот мое понимание.
Извините за слишком быструю публикацию, и все же спасибо за ваш быстрый ответ.