Architekt hat geschrieben:Ich dachte das wäre aus dem Snippet ersichtlich.
Ich kann aus dem Code rauslesen was er macht. Aber das scheint ja nicht das gleiche zu sein wie das was du erwartest.
Außerdem erleichterst du mir damit die Arbeit und ersparst mir Zeit - was der Motivation über das eigentliche Problem nachzudenken auch nicht schadet.
Architekt hat geschrieben:Ich erwarte, dass der Compiler mir Recht gibt, dass 42 == 42 ist. Demnach sollte er in das Label 'equal' springen und dort die Variable in 0(%esp) (die derzeit auf 1 steht) inkrementieren. Stattdessen geht er natürlich ins Label 'nequal' und dekrementiert die Variable. Ich erwarte also eig. die Ausgabe 2 (1 + 1) und nicht 0 (1 - 1). Doch irgendwie ist 42 != 42.
Das ist dein Problem:
Code: Alles auswählen
cmpl %eax, 0(%esp) # Vergleichen von Register (42) und Stack (42)
addl $4, %esp # Stack bereinigen wegen push
je equal # Wenn equal (42 == 42) springe zu equal
"cmp" ist auf CPU-Ebene eine Subtraktion, die (wie auch jede andere arithmetische Operation) Bits im Flags-Register setzt. "je" prüft auf Gleichheit, indem es sich den Wert des Zero-Flags im Flag-Register ansieht. Das Zero-Flag ist genau dann gesetzt, wenn die vorhergehende Operation 0 als Ergebnis hatte. Das ist bei einer Subtraktion natürlich genau dann der Fall, wenn die beiden Operanden den gleichen Wert hatten.
Du addierst jedoch zwischen "cmp" und "je" noch 4 zu esp, was die Flags erneut setzt, eben in Bezug auf das "add". Eine Addition zu esp wird in einem gültigen Programm nie 0 ergeben, also wird dein Zero-Flag wieder auf 0 gesetzt und dein "je" nicht ausgeführt.
Kurz: Keine Instruktionen zwischen cmp und jX (je, jg, jz, ...), wenn du dir nicht 100% sicher bist was du tust.