Pourquoi GCC émet-il « lea » au lieu de « sub » pour la soustraction ?
-
12-12-2019 - |
Question
Je regarde un assemblage généré en désassemblant certains programmes C et je suis confus par une seule optimisation que je vois fréquemment répétée.
Lorsque je n'ai aucune optimisation sur le compilateur GCC, j'utilise le subl
instruction de soustraction, mais lorsque les optimisations sont activées (-O3
pour être précis), le compilateur utilise un leal
instruction au lieu de soustraction, exemple ci-dessous :
sans optimisations :
83 e8 01 subl $0x1, %eax
avec des optimisations
8d 6f ff leal -0x1(%edi), %ebp
Ces deux instructions font 3 octets, je ne vois donc pas d’optimisation ici.Quelqu'un pourrait-il m'aider et essayer de m'expliquer le choix du compilateur ?
Toute aide serait appréciée.
La solution
C'est difficile à dire sans voir le code C original qui produit cela.
Mais si je devais deviner, c'est parce que le leal
permet d'effectuer la soustraction hors de propos sans détruire le registre source.
Cela peut économiser un déplacement de registre supplémentaire.
Le premier exemple :
83 e8 01 subl $0x1, %eax
écrase %eax
détruisant ainsi la valeur originale.
Le deuxième exemple :
8d 6f ff leal -0x1(%edi), %ebp
magasins %edi - 1
dans %ebp
. %edi
est conservé pour une utilisation future.
Autres conseils
Gardez également à l'esprit que lea
n'affecte pas les drapeaux alors que sub
fait.Donc, si les instructions suivantes ne dépendent pas de la mise à jour des drapeaux par la soustraction, alors pas la mise à jour des drapeaux sera également plus efficace.