Ich habe gerade ein einfaches C-Programm mit einer if-Anweisung ausprobiert und analysiert seine Montage. Sein Verhalten ist jedoch sehr unterschiedlich, wenn das -O2-Flag zur Kompilierung verwendet wird.Verständnis Assembly: -O2 wenn Verzweigung
Der C-Code für das gleiche ist: -
#include<stdio.h>
int main(int argc, char **argv) {
int a;
if(a<0) {
printf("A is less than 0\n");
}
}
und die entsprechende Baugruppe ist: -
main:
push %ebp
mov %ebp, %esp
sub %esp, 8
and %esp, -16
sub %esp, 16
test %eax, %eax
js .L4
leave
ret
.p2align 4,,15
.L4:
sub %esp, 12
push OFFSET FLAT:.LC0
call puts
add %esp, 16
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.6"
ich gelesen, dass die test
Anweisung im Grunde führt nur die logische UND-Verknüpfung der zwei Operanden . Ich lese auch, dass die js
Anweisung einen Sprung ausführt, wenn in der vorherigen Anweisung ein Zeichenwechsel erfolgt. Also, test
ing eax mit eax würde geben 0
oder 1
und der Sprung würde davon abhängen.
Ich verstehe nicht, wie es hier für die Verzweigung verwendet wird. Könnte jemand erklären, wie das funktioniert?
Ein guter Compiler sollte das ganze Programm auf nichts optimieren, da es undefiniertes Verhalten hat (Verwendung einer nicht initialisierten Variablen). Oder, wenn "a" initialisiert wurde, sollte es die Bedingung basierend auf dem Wert von "a" optimieren. –