He intentado obtener una comprensión más profunda de cómo los compiladores generan códigos de máquina, y más específicamente cómo GCC trata con la pila. Al hacerlo, he estado escribiendo simples programas en C, compilándolos para ensamblar y haciendo todo lo posible por comprender el resultado. He aquí un programa simple y la salida que genera:Asignación de pila, relleno y alineación
asmtest.c
:
void main() {
char buffer[5];
}
asmtest.s
:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
leave
ret
Lo desconcertante para mí es la razón por 24 bytes se asignan para la pila. Sé que debido a la forma en que el procesador aborda la memoria, la pila debe asignarse en incrementos de 4, pero si este fuera el caso, solo deberíamos mover el puntero de la pila en 8 bytes, no en 24. Como referencia, un buffer de 17 los bytes producen un puntero de pila movido 40 bytes y ningún buffer en absoluto mueve el puntero de pila 8. Un buffer entre 1 y 16 bytes inclusive mueve ESP
24 bytes.
Suponiendo que los 8 bytes son una constante necesaria (¿para qué se necesita?), Esto significa que estamos asignando en fragmentos de 16 bytes. ¿Por qué el compilador se estaría alineando de esa manera? Estoy usando un procesador x86_64, pero incluso una palabra de 64 bits solo debería requerir una alineación de 8 bytes. ¿Por qué la discrepancia?
Como referencia, estoy compilando esto en una Mac con 10.5 ejecutando gcc 4.0.1 y sin optimizaciones habilitadas.
hizo "push% ebp" hecho esp disminuido en 8 byte? más 8 bytes de ret, ya debería estar alineado con 16 bytes. ¿Por qué el compilador de dosis necesita estos 8 bytes adicionales? –
oh, lo tengo. Esta es una maquina de 32 bits. Lo siento.Debe ser ret 4 byte + ebp 4 byte + alineado 8 byte + búfer 16 –
Las versiones actuales de las ABI i386 y x86-64 System V requieren una alineación de 16B stack (antes de una instrucción 'call'), por lo que las funciones pueden asumir ese. Históricamente, el i386 ABI solo requería la alineación 4B. (Consulte https://stackoverflow.com/tags/x86/info para obtener enlaces a documentos ABI). GCC también mantiene '% esp' alineado incluso en funciones de hoja (que no llaman a otras funciones), cuando tiene que reservar espacio, y eso es lo que está sucediendo aquí. –