Warum gibt GCC zur Subtraktion „lea“ statt „sub“ aus?
-
12-12-2019 - |
Frage
Ich schaue mir eine Assembly an, die durch die Disassemblierung einiger C-Programme generiert wurde, und bin verwirrt über eine einzelne Optimierung, die sich häufig wiederholt.
Wenn ich keine Optimierungen am GCC-Compiler habe, verwendet er das subl
Anweisung zur Subtraktion, aber wenn ich Optimierungen aktiviert habe (-O3
um genau zu sein) verwendet der Compiler a leal
Anweisung statt Subtraktion, Beispiel unten:
ohne Optimierungen:
83 e8 01 subl $0x1, %eax
mit Optimierungen
8d 6f ff leal -0x1(%edi), %ebp
Beide Anweisungen sind 3 Byte lang, daher sehe ich hier keine Optimierung.Könnte mir jemand helfen und versuchen, die Wahl des Compilers zu erklären?
Jede Hilfe wäre dankbar.
Lösung
Es ist schwer zu sagen, ohne den ursprünglichen C-Code zu sehen, der dies erzeugt.
Aber wenn ich raten müsste, dann liegt es daran, dass leal
ermöglicht, dass die Subtraktion fehl am Platz durchgeführt wird, ohne das Quellregister zu zerstören.
Dadurch kann ein zusätzlicher Registerzug eingespart werden.
Das erste Beispiel:
83 e8 01 subl $0x1, %eax
überschreibt %eax
Dadurch wird der ursprüngliche Wert zerstört.
Das zweite Beispiel:
8d 6f ff leal -0x1(%edi), %ebp
Shops %edi - 1
hinein %ebp
. %edi
bleibt für die zukünftige Verwendung erhalten.
Andere Tipps
Denken Sie auch daran lea
hat keinen Einfluss auf die Flags, während sub
tut.Wenn also die folgenden Anweisungen nicht davon abhängen, dass die Flags durch die Subtraktion aktualisiert werden, dann nicht Auch das Aktualisieren der Flags wird effizienter sein.