2012-10-02 10 views
9

Sto osservando alcuni assembly che sono stati generati smontando alcuni programmi C e sono confuso da una singola ottimizzazione che vedo ripetuta frequentemente.Perché GCC emette "lea" invece di "sub" per la sottrazione?

Quando ho nessuna ottimizzazione sul compilatore GCC utilizza l'istruzione subl per sottrazione, ma quando devo ottimizzazioni attivata (-O3 per la precisione) il compilatore utilizza un'istruzione invece di sottrazione leal, l'esempio qui sotto:

senza ottimizzazioni:

83 e8 01  subl $0x1, %eax 

con le ottimizzazioni

8d 6f ff  leal -0x1(%edi), %ebp 

Entrambe queste istruzioni sono lunghe 3 byte, quindi qui non vedo un'ottimizzazione. Qualcuno potrebbe aiutarmi e cercare di spiegare la scelta del compilatore?

Qualsiasi aiuto sarebbe apprezzato.

risposta

13

È difficile dirlo senza vedere il codice C originale che produce questo.

Ma se dovessi indovinare, è perché il leal consente di eseguire la sottrazione fuori posto senza distruggere il registro sorgente.

Questo può salvare un movimento di registro aggiuntivo.


Il primo esempio:

83 e8 01  subl $0x1, %eax 

sovrascrive %eax distruggendo in tal modo il valore originale.

Il secondo esempio:

8d 6f ff  leal -0x1(%edi), %ebp 

esercizi %edi - 1 in %ebp. %edi è conservato per uso futuro.

+0

Non l'avevo considerato da questa prospettiva perché la versione non ottimizzata utilizza solo valori immediati nelle sottrazioni. Grazie, questo è stato molto utile. –

10

Ricordare inoltre che lea non ha effetto sulle bandiere mentre lo fa sub. Quindi se le istruzioni che seguono non dipendono dai flag che vengono aggiornati dalla sottrazione, allora non aggiornando i flag sarà anche più efficiente.

+0

Se 'lea' non ha effetto sui flag, allora come è equivalente a' sub'? Non dovrebbe influire sulle bandiere per avere lo stesso effetto di 'sub'? – crisron

+1

@crisron non sono equivalenti e servono a scopi diversi. Se non vuoi/hai bisogno di effetti collaterali, usa lea, altrimenti usa sub –

Problemi correlati