I understand the convention of decrementing %rsp
to reserve space for local variables at the beginning of a function in x86-64 assembly. However, in the below function, %rsp
is decremented but the reserved space of 8 bytes on the stack is never used in the function. So why would the compiler decrement %rsp
at the beginning? Source code and compiler information are not available.
0000000000400ef0 <phase_1>:
0x0000000000400ee0 <+0>: sub $0x8, %rsp
0x0000000000400ee4 <+4>: mov $0x402400, %esi
0x0000000000400ee9 <+9>: callq 0x401338 <strings_not_equal>
0x0000000000400eee <+14>: test %eax, %eax
0x0000000000400ef0 <+16>: je 0x400ef7 <phase_1+23>
0x0000000000400ef2 <+18>: callq 0x40143a <explode_bomb>
0x0000000000400ef7 <+23>: add $0x8, %rsp
0x0000000000400efb <+27>: retq
Any help would be much appreciated.
EDIT:
If the reason is to give the stack 16-byte alignment, here is another example that seems to be a contradiction. Doesn't subq $16, %rsp
at the beginning of call_incr
break the 16-bit alignment of stack prior to call incr
? Why not just decrement %rsp
by 8 bytes?
Source:
long incr(long *p, long val) {
long x = *p;
long y = x + val;
*p = y;
return x;
}
long call_incr() {
long v1 = 1000;
long v2 = incr(&v1, 3000);
return v1+v2;
}
Assembly (compiled with gcc -Og -fno-stack-protector -S
)
incr:
.LFB0:
.cfi_startproc
movq (%rdi), %rax
addq %rax, %rsi
movq %rsi, (%rdi)
ret
.cfi_endproc
call_incr:
.LFB1:
.cfi_startproc
subq $16, %rsp # why decrement by 16 bytes here?
.cfi_def_cfa_offset 24
movq $1000, 8(%rsp)
movl $3000, %esi
leaq 8(%rsp), %rdi
call incr
addq 8(%rsp), %rax
addq $16, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc