Why alignment is 16 bytes in 64-bit architecture?

(gdb) disas foo Dump of assembler code for function foo: 0x00000000004004a8 <foo+0>: push %rbp 0x00000000004004a9 <foo+1>: mov %rsp,%rbp 0x00000000004004ac <foo+4>: mov 0x13c(%rip),%eax # 0x4005ee <__dso_handle+30> 0x00000000004004b2 <foo+10>: mov %eax,-0x10(%rbp) 0x00000000004004b5 <foo+13>: lea -0x10(%rbp),%rax 0x00000000004004b9 <foo+17>: add $0x18,%rax 0x00000000004004bd <foo+21>: mov %rax,%rdx 0x00000000004004c0 <foo+24>: mov $0x400498,%eax 0x00000000004004c5 <foo+29>: mov %eax,(%rdx) 0x00000000004004c7 <foo+31>: leaveq 0x00000000004004c8 <foo+32>: retq (gdb) l foo 8 void foo() { 9 char overme[4] = "WOW"; 10 *(int*)(overme+24) = (int)bad; 11 } 

Why not only 8 bytes?

+6
c x86-64 alignment
source share
2 answers

gcc does not "assign" this space to a variable. Rather, x86_64 abi requires the stack pointer to always be 16 byte aligned when calling functions, in case the callee uses SSE vectorized math. This is a really stupid and wasteful requirement (the caller must ensure alignment if he needs one), but the standard and gcc follow the standard. You can fix it with -mpreferred-stack-boundary=3 (8-byte alignment, minimum for 64-bit).

+6
source share

These are 8 bytes, not 16. The LEA command does not show any alignment, -0x10 is just the offset applied to the value of the RBP register. Probably to create the address of a small local array. If the code generator uses any SIMD instructions, then 16 may be relevant. None of them appear in the two-line question.

+1
source share

All Articles