test
ist wie and
, außer dass es nur FLAGS schreibt, wobei beide Eingänge unverändert bleiben. Mit zwei verschiedenen Eingängen ist es nützlich zu testen, ob einige Bits alle Null sind oder ob mindestens eine gesetzt ist. (z.B.test al, 3
setzt ZF, wenn EAX ein Vielfaches von 4 ist (und somit beide seiner niedrigen 2 Bits auf Null gesetzt sind).
test eax,eax
setzt alle Flags genau die gleiche Art und Weise, dass cmp eax, 0
würde:
- CF und geräumte (AND/Test nicht immer, dass, und Null Subtraktion erzeugt nie einen Übertrag)
- ZF, SF und PF nach dem Wert in EAX. (
a = a&a = a-0
)
(Mit Ausnahme der veralteten AF (Auxiliary-Carry-Flag verwendet, um ASCII/BCD Anweisungen). TEST leaves it undefined, aber CMP sets it "according to the result". Null, da Subtrahieren eines Übertrag von der vierten bis fünften Bit nicht produzieren kann, CMP sollte immer AF löschen).
TEST kleiner (keine unmittelbare) und manchmal schneller (kann Makro-Sicherung in einen Vergleichs- und Zweig UOP auf mehreren CPUs in mehr Fällen als CMP). That makes test
the preferred idiom for testing a register for zero or not. Der einzige allgemeine Grund für die Verwendung von CMP mit einer unmittelbaren 0 ist, wenn Sie mit einem Speicheroperanden vergleichen möchten (z. B. cmpb $0, (%esi)
, um nach einem abschließenden Nullbyte am Ende einer C-style-Zeichenfolge mit impliziter Länge zu suchen). .
AVX512F fügt kortestw k1, k2
und AVX512DQ/BW (Skylake aber nicht KNL) in ktestb/w/d/q k1, k2
, die auf AVX512 Maskenregister (k0..k7) arbeiten, aber immer noch gesetzt regelmäßige FLAGS wie test
tut, die gleiche Weise, Ganzzahl OR
oder AND
Anweisungen tun.
kortestw k1,k1
ist der idiomatische Weg/verzweigen cmovcc/setcc basierend auf einem Ergebnis AVX512 vergleichen, ersetzt SSE/AVX2 (v)pmovmskb/ps/pd
+ test
oder cmp
.
Verwendung von jz
vs. je
kann verwirrend sein.
jz
and je
are literally the same instruction, d.h. derselbe Opcode im Maschinencode. Sie tun das gleiche, aber haben unterschiedliche semantische Bedeutung für Menschen. Disassemblierer (und typischerweise asm, die von Compilern ausgegeben werden) verwenden immer nur einen, so dass die semantische Unterscheidung verloren geht.
cmp
und sub
setzen Sie ZF, wenn ihre beiden Eingänge gleich sind (d. H. Das Subtraktionsergebnis ist 0). je
(Sprung wenn gleich) ist das semantisch relevante Synonym.
test %eax,%eax
/and %eax,%eax
setzt erneut ZF, wenn das Ergebnis Null ist, aber es gibt keinen "Gleichheitstest". ZF nach Test sagt Ihnen nicht, ob die beiden Operanden gleich waren. Also jz
(Sprung wenn Null) ist das semantisch relevante Synonym.
Ich machte eine Bearbeitung, um diese populäre Antwort in eine bessere kanonische Antwort auf "was ist das TEST-Ding alles über, und wie ist es anders als CMP", was implizit ist. Siehe meine eigene Antwort weiter unten für Kommentare zur semantischen Bedeutung von JE und JZ. Bitte überprüfe meine Bearbeitung, da sie ziemlich wichtig ist und immer noch deine Antwort ist. –
@PeterCordes Ich schätze die Absicht, aber ich werde Ihre Bearbeitung rückgängig machen. 1. Ihre "Stimme" ist sehr verschieden von meiner, und im Moment liest es sich viel mehr wie Ihre Antwort als meine. 2. Problematischer ist die fette Behauptung, dass die Flags zwischen "test" und "cmp" genau gleich herauskommen. Ja, ich verstehe, dass Sie aufgrund Ihrer Kommentare zu Cody davon überzeugt sind. Es ist jedoch etwas anderes, es in meinen Posten zu legen. es ist keine Behauptung, ich bin bereit zu stehen, einfach weil ich nicht weiß, ob es in allen Fällen identisch ist. –
@PeterCordes Ich verstehe den Wunsch, eine "kanonische" Antwort zu haben, aber ich denke, Ihre Antwort muss auf eigene Kosten schwimmen oder sinken, anstatt auf eine akzeptierte Antwort zu paddeln. Ich musste das auch für einige meiner Antworten auf sehr populäre Fragen tun, wie zum Beispiel die [floating-point primer one] (http://stackoverflow.com/a/27030789/13), die zum Zeitpunkt der Veröffentlichung meiner Antwort hatte bereits andere Antworten mit 500 Upvotes. –