[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: