Andrew Tomazos wrote:
I've been studying the x86 compiled form of the following function:
void function()
{
char buffer[X];
}
where X = 0, 1, 2 .. 100
Naively, I would expect to see:
pushl %ebp
movl %esp, %ebp
subl $X, %esp
leave
ret
Instead, the stack appears to be padded:
For a buffer size of 0 the stack size is 0
For a buffer size of 1 to 7 the stack size is 16
For a buffer size of 8 to 12 the stack size is 24
For a buffer size of 13 to 28 the stack size is 40
For a buffer size of 29 to 44 the stack size is 56
For a buffer size of 45 to 60 the stack size is 72
For a buffer size of 61 to 76 the stack size is 88
For a buffer size of 77 to 92 the stack size is 104
For a buffer size of 93 to 100 the stack size is 120
When X >= 8 gcc adds a stack corruption check (__stack_chk_fail),
which accounts for an extra 4 bytes of stack space in these cases.
This does not explain the rest of the padding. Can anyone explain the
purpose of the rest of the padding?
This looks like more of a gcc-help question, trying to move the thread
there. Unless you over-ride defaults with -mpreferred-stack boundary
(or -Os, which probably implies a change in stack boundary), or ask for
a change on the basis of making a leaf function, you are generating
alignment compatible with the use of SSE parallel instructions. The
stack, then, must be 16-byte aligned before entry and at exit, and also
a buffer of 16 bytes or more must be 16-byte aligned.
I believe there is a move afoot to standardize the treatment for the
most common x86 32-bit targets; that was done at the beginning for
64-bit. Don't know if you are using x86 to imply 32-bit, in accordance
with Windows terminology.