Ho cercato di comprendere meglio come i compilatori generano il codice macchina e in particolare come GCC gestisce lo stack. Così facendo ho scritto programmi C semplici, li ho compilati in assemblea e ho fatto del mio meglio per capirne l'esito. Ecco un semplice programma e l'uscita che genera:Assegnazione, riempimento e allineamento dello stack
asmtest.c
:
void main() {
char buffer[5];
}
asmtest.s
:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
leave
ret
Che cosa sconcertante per me è il motivo per cui 24 byte vengono allocate per lo stack. So che a causa del modo in cui il processore indirizza la memoria, lo stack deve essere allocato in incrementi di 4, ma se questo fosse il caso, dovremmo spostare il puntatore dello stack di 8 byte, non 24. Come riferimento, un buffer di 17 byte produce un puntatore dello stack spostato di 40 byte e nessun buffer sposta il puntatore dello stack 8. Un buffer compreso tra 1 e 16 byte inclusi sposta ESP
24 byte.
Ora supponendo che gli 8 byte siano una costante necessaria (cosa è necessario per?), Ciò significa che stiamo allocando in blocchi di 16 byte. Perché il compilatore dovrebbe essere allineato in questo modo? Sto usando un processore x86_64, ma anche una parola a 64 bit dovrebbe richiedere solo un allineamento a 8 byte. Perché la discrepanza?
Per riferimento, lo sto compilando su un Mac che esegue 10.5 con gcc 4.0.1 e nessuna ottimizzazione abilitata.
ha fatto "push% ebp" fatto esp diminuito di 8 byte? più gli 8 byte di ret, dovrebbero già essere allineati con 16 byte. Perché il compilatore di dose ha bisogno di questi 8 byte aggiuntivi? –
oh, ho capito. Questo è un machince a 32 bit. Scusate.Dovrebbe essere ret 4 byte + ebp 4 byte + allineati 8 byte + buffer 16 –
Le versioni correnti degli iSi System V i386 e x86-64 richiedono l'allineamento dello stack 16B (prima di un'istruzione 'call'), quindi le funzioni possono assumere quella. Storicamente, l'ABI i386 richiedeva solo l'allineamento 4B. (consultare https://stackoverflow.com/tags/x86/info per i collegamenti ai documenti ABI). GCC mantiene anche '% esp' allineato anche nelle funzioni foglia (che non chiamano altre funzioni), quando deve riservare qualsiasi spazio, e questo è quello che sta succedendo qui. –