OT - per soli programmatori
mi scusassero per l'OT,
ma 'sfrutto' questa ml per un help che non riguarda strettamente
debian, e invito chiunque possa dirmi qualcosa a rispondermi in privato.
il mio problema è la generazione di codice da parte del gcc, che, ahime,
mi e' sembrata davvero pessima (ho il gcc versione 2.95.2 di potato, ma ho
anche provato con il gcc 2.95.4 di redhat). naturalmente spero che si
tratti della mia ignoranza e non del gcc. so che esiste la ml del gcc, ma
magari qualcuno conosce già la risposta (ho cmq cercato negli archivi
senza trovare mai un riferimento a questo problema, il che mi
insospettisce un po', ho anche chiesto sui canali irc #c e #gcc di
irc.openprojects.net, ma nessuno ha saputo dirmi niente, anzi, sono
rimasti allibiti, e a me è caduto un mito :| ).
prendiamo questo programmino millimetrico:
int somma(int a, int b) {
return a+b;
}
int main() {
int a, risultato;
a = 4;
risultato=somma(a,5);
return 0;
}
lasciando perdere le questioni stilistiche relative al codice sopra (del
tipo "ah, ma 'a' è da subito quattro perchè non scrivi int a=4?"),
personalmente mi aspetterei un codice asm che assomigli a questo:
pushl %ebp
movl %esp,%ebp
movl $4, %eax
pushl $5
pushl %eax
call somma
addl $8, %esp
xorl %eax, %eax
movl %ebp, %esp
popl %ebp
vediamo cosa genera il gcc (senza alcuno switch di ottimizzazione):
$ gcc -S prova.c
ecco la funzione main:
main:
pushl %ebp ; ok questo è
movl %esp,%ebp ; il prologo
subl $24,%esp <-- a che serve 'sta riga?
movl $4,-4(%ebp)
addl $-8,%esp <-- e quest'altra ?
pushl $5
movl -4(%ebp),%eax
pushl %eax
call somma
addl $16,%esp
movl %eax,%eax <-- qui mi pare stia giusto facendo
un po' di allineamento
movl %eax,-8(%ebp)
xorl %eax,%eax
jmp .L3
.p2align 4,,7
.L3
leave
ret
ok, direte voi, ma il codice non era ottimizzato (fatto sta che è _molto_
non ottimizzato...). Quindi in questo caso, la domanda specifica è, perchè
lo stack viene gestito in questo modo?
Vediamo cosa succede compilando in questo modo (cioè come viene compilata
la maggior parte del software, con le ottimizzazioni usuali) :
$ gcc prova.c -S -O2 -fomit-frame-pointer
(stesso risultato si ottiene con
-Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common
che non è altro che la sequela di switch per la compilazione del kernel)
main:
subl $12,%esp <-- Ma perchè due istruzioni
addl $-8,%esp <-- al posto di una?
pushl $5
pushl $4 ; questa è di fatto un'ottimizzazione
call somma
xorl %eax,%eax ; anche qui, ottimo
addl $16,%esp <-- due al posto di una:
addl $12,%esp <-- addl $28, %esp no?
ret
e fortuna che il codice è ottimizzato :/ . se immagino sta roba per
programmi molto grandi (-> mozilla, ma magari ha una riga di compilazione
con switch diversi, non ho controllato) mi vengono i brividi. La cosa che
più mi lascia sconvolto è che non stiamo parlando di ottimizzazione di
'strani' algoritmi matematici, o di robe relative ad uno specifico
processore, ma dell'handling dello stack. Nè mi si dica che un 'add
costante, esp' è un opcode che viene eseguito con pochi cicli di clock...
any hints?
mi scuso con tutti coloro che non sono interessati direttamente
all'argomento, ma se il gcc ha un problema, ce l'ha anche debian (fino a
prova contraria, tutti usano il gcc per compilare il software che usiamo
tutti i giorni).
soon,
lidl
--
.-.
Free source for free users! /v\ L I N U X
// \\ >Phear the Penguin<
/( )\
^^-^^
Reply to: