The original System V Unix ABI for IA-32 (Intel386) required the stack pointer to be aligned on a 4 byte boundary.1 The (unpublished) Linux ABI for IA-32 was based on the original System V Unix ABI, but in February 2015 an updated Linux IA-32 ABI Version 1.0 was published that required the stack pointer to be aligned to a 16 (32 if __m256
is passed on stack) byte boundary when calling a function.2 (This ABI was updated to Version 1.1 in December 2015,3 which as far as I know is the latest at the time of writing.)
The compiler's preamble code for the function call usually assumes that the stack is already aligned on entry. It assumes that %esp+4
(the +4
accounts for the return address on the stack) is aligned to a 16 (or 32) byte boundary, and it ensures that the stack pointer is decreased by a multiple of 16 (and aligned to a multiple of 32 if necessary) when calling another function. It does that even if the called function does not call another function.
For the preamble below:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
Before the first instruction (pushl %ebp
), %esp+4
is aligned to a 16 byte boundary. After the first instruction, %esp+4+4
is aligned to a 16 byte boundary. After the third instruction (subl $24, %esp
), %esp+4+4+24
is aligned to a 16 byte boundary, and since 4+4+24 is a multiple of 16, %esp
is aligned to a 16 byte boundary.
The compiler could have replaced subl $24, %esp
with subl $8, %esp
and still kept the stack aligned to a 16 byte boundary. I do not know the reason for allocating the extra 16 bytes.
The GCC compiler for Linux had already been assuming the stack was already aligned to a 16 byte boundary for a number of years before the version 1.0 of the amended ABI was published. This caused GCC 4.4 to break several binaries. The "fix" was to change the ABI, breaking existing old code rather than fixing the compiler to be compatible with existing code.4
Footnotes:
- System V Application Binary Interface, Intel386™ Architecture Processor Supplement Fourth Edition —Figure 3-15: Standard Stack Frame.
- System V Application Binary Interface Intel386 Architecture Processor Supplement Version 1.0 — 2.2.2 The Stack Frame.
- System V Application Binary Interface Intel386 Architecture Processor Supplement Version 1.1
- Bug 40838 - gcc shouldn't assume that the stack is aligned — Comment 86 by H.J.Lu (2011-01-18 21:07:26 UTC):
I am in the process of updating i386 psABI to specify 16byte stack alignment.