¿Por qué el comstackdor asigna más de lo necesario en la stack?

Tengo un progtwig en C simple. Digamos, por ejemplo, que tengo un int y una matriz char de longitud 20. Necesito 24 bytes en total.

int main() { char buffer[20]; int x = 0; buffer[0] = 'a'; buffer[19] = 'a'; } 

La stack debe estar alineada con un límite de 16 bytes, por lo que supongo que un comstackdor reservará 32 bytes. Pero cuando compilo un progtwig de este tipo con gcc x86-64 y leo el ensamblaje de salida, el comstackdor se reserva 64 bytes.

 ..\gcc -S -o main.s main.c 

Me da:

  .file "main.c" .def __main; .scl 2; .type 32; .endef .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: pushq %rbp # RBP is pushed, so no need to reserve more for it .seh_pushreg %rbp movq %rsp, %rbp .seh_setframe %rbp, 0 subq $64, %rsp # Reserving the 64 bytes .seh_stackalloc 64 .seh_endprologue call __main movl $0, -4(%rbp) # Using the first 4 bytes to store the int movb $97, -32(%rbp) # Using from RBP-32 movb $97, -13(%rbp) # to RBP-13 to store the char array movl $0, %eax addq $64, %rsp # Restoring the stack with the last 32 bytes unused popq %rbp ret .seh_endproc .ident "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 5.2.0" 

¿Porqué es eso? Cuando programo el ensamblaje, siempre reservo la memoria mínima que necesito sin ningún problema. ¿Es eso una limitación del comstackdor que tiene problemas para evaluar la memoria necesaria o hay alguna razón para ello?

Aquí está gcc -v

 Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=D:/Mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/5.2.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-5.2.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw520/x86_64-520-posix-seh-rt_v4-rev0/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw520/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw520/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw520/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw520/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/c/mingw520/x86_64-520-posix-seh-rt_v4-rev0/mingw64/opt/include -I/c/mingw520/prerequisites/x86_64-zlib-static/include -I/c/mingw520/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/c/mingw520/x86_64-520-posix-seh-rt_v4-rev0/mingw64/opt/include -I/c/mingw520/prerequisites/x86_64-zlib-static/include -I/c/mingw520/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/c/mingw520/x86_64-520-posix-seh-rt_v4-rev0/mingw64/opt/lib -L/c/mingw520/prerequisites/x86_64-zlib-static/lib -L/c/mingw520/prerequisites/x86_64-w64-mingw32-static/lib ' Thread model: posix gcc version 5.2.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 

Los comstackdores pueden reservar memoria adicional para ellos mismos.

Gcc tiene una bandera, -mpreferred-stack-boundary , para establecer la alineación que mantendrá. De acuerdo con la documentación , el valor predeterminado es 4, que debe producir una alineación de 16 bytes, que es necesario para las instrucciones de SSE.

Como VermillionAzure señaló en un comentario , debe proporcionar su versión de gcc y las opciones de tiempo de comstackción (use gcc -v para mostrarlas).

Porque no has habilitado la optimización.

Sin optimización, el comstackdor no intenta minimizar la cantidad de espacio o tiempo que necesita para cualquier cosa en el código generado, simplemente genera código de la manera más directa posible.

Agregue -O2 (o incluso solo -O1 ) o -Os si desea que el comstackdor produzca un código decente.

Necesito 24 bytes en total.

El comstackdor necesita espacio para una dirección de retorno y un puntero base. Como estás en modo de 64 bits, son otros 16 bytes. Total 40. Redondea eso hasta un límite de 32 bytes y obtienes 64.