Why do we use sub $0x18, %rsp?

assembly, x86-64

Solution

"I know `sub $12, %esp` as same as three time on `pop %eax` and `mov $0, %eax`." You know wrong. `sub $12, %esp` does not change `eax`, neither by popping into it nor by moving a 0 into it.

The primary/direct reason for using something like `sub $12, %esp` is to reserve some space on the stack. That can be used to give some space to local variables of a subroutine. That can also be used to align the stack pointer if it's desirable for performance or other reasons.

`add $18, %rsp` does the reverse, it releases the space previously allocated on the stack. This can be used to free the space occupied by local variables or by the parameters that have been previously passed to another subroutine and aren't needed on the stack anymore.

Problem

I studied 32 bit machine, and I know sub $12, %esp as same as three time on pop %eax and mov $0, %eax. But I don't know why we use add $18, %rsp with start procedure call or sub $18, %rsp start with procedure call at x86-64 machine. Why does compiler use this rule for procedure call? Argument rule? ``` 0x0000000000400df3 <main+191>: mov $0x402227,%edi 0x0000000000400df8 <main+196>: callq 0x400ab8 <puts@plt> 0x0000000000400dfd <main+201>: callq 0x4014c0 <read_line> 0x0000000000400e02 <main+206>: mov %rax,%rdi 0x0000000000400e05 <main+209>: callq 0x401139 <phase_3> ----------------------------------------------------------------------- example: 0x0000000000401139 <example+0>: sub $0x18,%rsp 0x000000000040113d <example+4>: lea 0x8(%rsp),%rcx 0x0000000000401142 <example+9>: lea 0xc(%rsp),%rdx 0x0000000000401147 <example+14>: mov $0x40248a,%esi 0x000000000040114c <example+19>: mov $0x0,%eax 0x0000000000401151 <example+24>: callq 0x400ac8 <__isoc99_sscanf@plt> 0x0000000000401156 <example+29>: cmp $0x1,%eax ```

Original source