3

I saw that the stack is aligned by 4 bytes on x86-32 and 8 bytes on x86-64. but how does this alignment work? For example in the code below, it has the following output

#include<stdio.h>

int main()
{ 
   short x = 2;
   short y = 4;
   return 0;
}

Debugging I have the following output

(gdb) disas main
Dump of assembler code for function main:
   0x0000555555554660 <+0>:     push   rbp
   0x0000555555554661 <+1>:     mov    rbp,rsp
   0x0000555555554664 <+4>:     mov    WORD PTR [rbp-0x2],0x2
   0x000055555555466a <+10>:    mov    WORD PTR [rbp-0x4],0x4
=> 0x0000555555554670 <+16>:    mov    eax,0x0
   0x0000555555554675 <+21>:    pop    rbp
   0x0000555555554676 <+22>:    ret    
End of assembler dump.
(gdb) i r rbp
rsp            0x7fffffffe710   0x7fffffffe710
(gdb) x/xb $rbp - 0x2
0x7fffffffe70e: 0x02

Notice that the initial address of rbp (0x7fffffffe710) has the binary value 11111111111111111111111111111111110011100010000, with 4 lower bits zeroed 2 ^ 4 = 16, does this mean that the alignment is 16 bytes? Already at the address of variable x (0x7fffffffe70e) it has the binary value 11111111111111111111111111111111110011100001110, it has 1 lower bit reset 2 ^ 1 = 2, after all, what is the stack alignment? Would it be the starting address of rbp?

  • 1
    If an address is aligned to 16 bytes, it is _also_ aligned to 8 bytes, 4 bytes, 2 bytes, 1 byte. Just because this address has 16-byte alignment does not tell you anything about whether the alignment is guaranteed to be 16 bytes. It might be less. – paddy Jul 17 '20 at 04:30
  • How do I have this guarantee then? @paddy – Yuri Bittencourt Jul 17 '20 at 04:43
  • 1
    The guarantee comes from the toolchain specifying and implementing a specific alignment. What toolchain are you using? – old_timer Jul 17 '20 at 05:01
  • gcc version 6.3 running on a debian linux on the x86-64 architecture – Yuri Bittencourt Jul 17 '20 at 05:09
  • The i386 System V ABI on modern GNU/Linux *also* requires / guarantees 16-byte stack alignment before a `call`. Some non-Linux systems (and very old Linux) don't guarantee 16 byte stack alignment in 32-bit code, but Linux does. – Peter Cordes Jul 17 '20 at 09:26
  • But would this stack alignment be called the initial address of rsp, which is contained in rbp? because when declaring variables of various types, each one will have its own alignment, or the alignment of the stack, which means the alignment of all addresses subtracted from the data types? @PeterCordes – Yuri Bittencourt Jul 17 '20 at 16:28
  • 1
    The compiler knows where a 16-byte alignment boundary is on entry to every function (RSP - 8). Using this, it can align every stack variable to at least its `alignof(T)`. Note that using RBP as a frame pointer is optional; try compiling something with optimization enabled ([How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)) – Peter Cordes Jul 17 '20 at 17:08
  • I have difficulty understanding the terminology, when I say that the stack is aligned by 16 bytes, it means that the rsp address, before a function call is aligned by a multiple of 16, that's it ? @PeterCordes – Yuri Bittencourt Jul 17 '20 at 17:29
  • Yes, that's what being aligned means. i.e. after one push, `test rsp, 0xf` would set ZF, because the low 4 bits of the address are zero. – Peter Cordes Jul 17 '20 at 17:58
  • Will you come up with any article or paper that addresses this whole issue? – Yuri Bittencourt Jul 17 '20 at 18:00
  • 1
    https://en.wikipedia.org/wiki/Data_structure_alignment#Definitions explains what alignment is. The x86-64 System V ABI document itself is clear on what the rules / expectations are that functions can depend on, and how various types need to be aligned. ([Where is the x86-64 System V ABI documented?](https://stackoverflow.com/a/40348010)) Other Q&As just state facts based on it, like [Should %rsp be aligned to 16-byte boundary before calling a function in NASM?](https://stackoverflow.com/q/62714764) and [Understanding stack alignment enforcement](https://stackoverflow.com/a/47415408) – Peter Cordes Jul 17 '20 at 18:06
  • Thank you very much! – Yuri Bittencourt Jul 17 '20 at 18:15

0 Answers0