Unterschied zwischen "oder eax, eax" und "test eax, eax" [duplizieren]

8

Was ist der Unterschied zwischen or eax,eax und test eax,eax ? Ich habe gesehen, dass verschiedene Compiler beide für den gleichen Vergleich produzieren und soweit die Dokumentation geht, machen sie genau das Gleiche, also frage ich mich, warum sie nicht alle test eax,eax verwenden. Wenn man darüber nachdenkt, würde and eax,eax die Flags auf identische Weise setzen, aber ich habe es weder in Freepascal, Delphi noch in msVC ++ gesehen.

Ich habe einige asm-Blöcke in Delphi kompiliert und die Assembler-Quelle ausgecheckt und alle drei Formen haben die gleiche Länge in Opcodes und haben auch die Intel-Performance-PDF überprüft und sie haben die gleiche Latenz und den gleichen Durchsatz.

Bearbeiten:
Die Frage betrifft insbesondere den Unterschied zwischen den spezifischen Fällen test eax,eax , or eax,eax und and eax,eax . Alle 3 ergeben völlig identische Ergebnisse für Register, Flags, Opcode-Länge, Latenz, Durchsatz. Und doch, wenn 0, wenn nicht Null, oder wenn signiert, einige Compiler test eax,eax verwenden, während einige or eax,eax verwenden, und ich frage mich, warum sie nicht alle test eax,eax verwenden, da es den Code sehr leicht macht klarer.

Bearbeiten2:
Als Referenz bin ich zu Hause und habe nur msvc ++ und Delphi hier und älter, aber testet eine Variable wenn Null, msvc ++ tut test eax,eax , während Delphi or eax,eax macht.

    
Marladu 16.05.2014, 03:05
quelle

3 Antworten

6

Im Allgemeinen besteht der einzige Unterschied zwischen test und and darin, dass test <reg>, <reg> seine Operanden nicht ändert. Im Wesentlichen wendet test eine Operation and an und verwirft den Nicht-Flag-Teil des Ergebnisses. Wenn die Operanden identisch sind, sind die Ergebnisse gleich (wie auch or ).

test kann aufgrund von Dingen wie Mikro-Op-Fusion eine überlegene Befehlswahl sein. Daher wird test normalerweise bevorzugt, es sei denn, die Berechnung müsste wiederholt werden. Dasselbe gilt für cmp / sub .

Durchsuchen Sie Intels Dokument für "Fusion" und Sie sollten die Details finden.

    
gsg 16.05.2014 05:33
quelle
2

Um nur ein wenig zu wiederholen und etwas hinzuzufügen, was @gsg angezeigt hat, führt die TEST-Anweisung einen bitweisen logischen Vergleich (im wesentlichen bitweise AND-Verknüpfung, aber nicht Speichern des Ergebnisses) von zwei Operanden durch und setzt die Prozessorflags entsprechend zu dem Ergebnis dieser Operation. Der ODER-Befehl führt ein logisches ODER der Quelle mit dem Ziel durch, speichert das Ergebnis im Ziel und setzt die Prozessorflags entsprechend dem Ergebnis. Beide beeinflussen die Prozessor-Flags auf die gleiche Weise. Wenn also die Operanden identisch sind, ist das Verhalten dasselbe. Flags unterscheiden sich nicht. Wenn die Operanden jedoch unterschiedlich sind, ist ihr Verhalten dann ganz anders. Sie können auch mit and eax,eax auf Null testen, was sich auch auf die Flags auswirkt.

    
lurker 16.05.2014 13:31
quelle
2

Die Schaltung zur Bestimmung, dass der Inhalt von eax nach test eax, eax derselbe ist wie vor der Anweisung, ist einfacher als die Schaltung, die erforderlich ist, um zu dieser Schlussfolgerung für or eax, eax zu gelangen. Aus diesem Grund ist test besser.

Einige Compiler haben möglicherweise or zu einem Zeitpunkt erzeugt, als es keinen Unterschied machte (vor der Ausführung außerhalb der Reihenfolge), aber es wird heutzutage bei einigen Prozessoren außerhalb der Reihenfolge einen Unterschied machen (während noch andere OOO-Prozessoren werden so ausgefeilt sein, dass sie or eax, eax als wirklich äquivalent zu test eax, eax ) erkennen werden.

Ich konnte keine Referenz finden, die rechtfertigt, dass einige moderne Prozessoren tatsächlich daraus schließen können, dass or reg, reg reg nicht modifiziert, aber hier ist eine Antwort, die behauptet, dies sei der Fall für xchg reg, reg .

    
Pascal Cuoq 16.05.2014 14:06
quelle