I am trying to understand how functions are called in C. When I disassemble this code (gcc - gdb; I am on Linux with an i5-3320M) to get the prologue of function toto
:
void nop(){return ;}
void toto(int i, int j)
{
return;
}
int main(int argc, char **argv)
{
int i = 1;
int* pt;
i = 0;
}
I get the prologue:
0x0000000000400523 <+0>: push %rbp
0x0000000000400524 <+1>: mov %rsp,%rbp
0x0000000000400527 <+4>: sub $0x8,%rsp
Here I don't understand why rsp
is decremented by 8 as I do not use a local variable in toto
. Moreover, if I do use a local variable:
void toto(int i, int j)
{
int i=1
return;
}
I get the following prologue:
0x0000000000400523 <+0>: push %rbp
0x0000000000400524 <+1>: mov %rsp,%rbp
0x0000000000400527 <+4>: sub $0x18,%rsp
And here I don't understand why rsp
is decremented by 0x18 (24 bytes). I would expect something like 16 bytes because I already have a mysterious offset of 8, plus I need 4 bytes for the int. But my architecture is 64 bit, a word in the stack can't be less than 8 bytes so 8+8 = 16.
The x86_64 ABI requires that upon entering a function, %rsp
be always a multiple of 16. Thus, after push %rbp
, %rsp
must be subtracted a value like 0x8, 0x18, 0x28 etc.
UPDATE. Sorry everyone who upvoted this, I deceived you. It can be easily seen that each push %rbp%
is always paired with a call
or callq
which gives 0x10 bytes, thus the extra value subtracted from %rsp
must be multiple of 0x10 as well.
As to your first question, you must be compiling without optimization. With optimization, all your functions collapse to mere repz retq
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With