Perché GCC emette "Lea" invece di "sub" per la sottrazione?
-
12-12-2019 - |
Domanda
Sto guardando un po 'di assemblaggio che è stato generato smontando alcuni programmi C e sono confuso da un'unica ottimizzazione che vedo ripetuta frequentemente.
Quando non ho ottimizzazioni sul compilatore GCC utilizza l'istruzione subl
per la sottrazione, ma quando ho acceso le ottimizzazioni (-O3
per essere preciso) Il compilatore utilizza un'istruzione leal
anziché la sottrazione, esempio seguente:
Senza ottimizzazioni:
83 e8 01 subl $0x1, %eax
.
con ottimizzazioni
8d 6f ff leal -0x1(%edi), %ebp
.
Entrambe queste istruzioni sono lunghe 3 byte, quindi non sto vedendo un'ottimizzazione qui.Qualcuno potrebbe aiutarmi e provare a spiegare la scelta del compilatore?
Qualsiasi aiuto sarebbe apprezzato.
Soluzione
È difficile da dire senza vedere il codice C originale che produce questo.
Ma se dovessi indovinare, è perché il leal
consente di fare la sottrazione di essere fuori posto senza distruggere il registro sorgente.
Questo può salvare una mossa di registro extra.
.
Il primo esempio:
83 e8 01 subl $0x1, %eax
.
Overwrites %eax
distruggendo così il valore originale.
Il secondo esempio:
8d 6f ff leal -0x1(%edi), %ebp
.
Memorizza %edi - 1
in %ebp
.%edi
è preservato per uso futuro.
Altri suggerimenti
Tieni presente che il lea
non influisce sui flag mentre sub
lo fa.Quindi se le istruzioni successive non dipendono dalle flag che vengono aggiornate dalla sottrazione, allora non l'aggiornamento dei flag sarà anche più efficiente.