Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why alignment is 16 bytes on 64 bit architecture? [duplicate]

(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 just 8 bytes?

like image 875
compile-fan Avatar asked Apr 04 '11 11:04

compile-fan


People also ask

Why does the stack need to be 16 byte aligned?

The compiler is maintaining a 16-byte alignment of the stack pointer when a function is called, adding padding to the stack as necessary. The compiler knows that the stack will always be aligned correctly, so it can emit instructions with alignment requirements without risk of triggering their fault conditions.

What does it mean to be 16 byte aligned?

This effectively means that the address of the memory your data resides in needs to be divisible by the number of bytes required by the instruction. So in your case the alignment is 16 bytes (128 bits), which means the memory address of your data needs to be a multiple of 16.

What is 64 bit alignment?

64-bit aligned is 8 bytes aligned). A memory access is said to be aligned when the data being accessed is n bytes long and the datum address is n-byte aligned. When a memory access is not aligned, it is said to be misaligned. Note that by definition byte memory accesses are always aligned.

Is malloc 16 byte aligned?

The GNU documentation states that malloc is aligned to 16 byte multiples on 64 bit systems.


2 Answers

gcc is not "assigning" this space to the variable. Rather, the x86_64 abi requires the stack pointer to always be 16-byte-aligned at function calls, in case the callee uses vectorized SSE math. It's a really stupid and wasteful requirement (the callee should ensure the alignment if it needs it), but that's the standard, and gcc follows the standard. You can fix it with -mpreferred-stack-boundary=3 (8 byte alignment, the minimum for 64-bit).

like image 137
R.. GitHub STOP HELPING ICE Avatar answered Sep 19 '22 13:09

R.. GitHub STOP HELPING ICE


It is 8 bytes, not 16. The LEA instruction doesn't show anything alignment related, -0x10 is just an offset applied to the value of the RBP register. Probably to generate the address of a small local array. If the code generator uses any SIMD instructions then 16 could be relevant. None of which is visible in a two-liner question.

like image 43
Hans Passant Avatar answered Sep 17 '22 13:09

Hans Passant