Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how rsp is decremented in prologue on a X86-64 architecture

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.

like image 776
GerardBouchar Avatar asked Oct 21 '22 03:10

GerardBouchar


1 Answers

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.

like image 110
ach Avatar answered Oct 23 '22 01:10

ach