test
ist wie and
, außer dass es nur FLAGS schreibt und beide Eingaben unverändert lässt. Mit zwei verschiedenen Eingängen ist es nützlich zu testen, ob einige Bits alle Null sind oder ob mindestens eines gesetzt ist. (z. B. test al, 3
setzt ZF, wenn EAX ein Vielfaches von 4 ist (und somit beide niedrigen 2 Bits auf Null gesetzt sind).
test eax,eax
setzt alle Flags genau die gleiche Art und Weise, cmp eax, 0
würde :
- CF und OF gelöscht (AND / TEST macht das immer; das Subtrahieren von Null erzeugt niemals einen Übertrag)
- ZF, SF und PF gemäß dem Wert in EAX. (
a = a&a = a-0
).
(PF wird wie gewohnt nur auf die niedrigen 8 Bits eingestellt )
Mit Ausnahme des veralteten AF (Auxiliary-Carry-Flag, das von ASCII / BCD-Anweisungen verwendet wird). TEST lässt es undefiniert , aber CMP setzt es "entsprechend dem Ergebnis" . Da das Subtrahieren von Null keinen Übertrag vom 4. zum 5. Bit erzeugen kann, sollte CMP immer AF löschen.
TEST ist kleiner (kein sofortiger) und manchmal schneller (kann in mehr Fällen als CMP auf mehr CPUs zu einem Vergleichs- und Verzweigungs-UOP verschmelzen). Das macht test
die bevorzugte Redewendung zum Vergleichen eines Registers mit Null . Es ist eine Gucklochoptimierung cmp reg,0
, die Sie unabhängig von der semantischen Bedeutung verwenden können.
Der einzige häufige Grund für die Verwendung von CMP mit einer unmittelbaren 0 ist, wenn Sie mit einem Speicheroperanden vergleichen möchten. Zum Beispiel, cmpb $0, (%esi)
um am Ende einer Zeichenfolge im C-Stil mit impliziter Länge nach einem abschließenden Null-Byte zu suchen.
AVX512F fügt hinzukortestw k1, k2
und AVX512DQ / BW (Skylake-X, aber nicht KNL) fügt hinzu ktestb/w/d/q k1, k2
, die mit AVX512-Maskenregistern (k0..k7) arbeiten, aber weiterhin reguläre FLAGS setzen, wie test
dies bei Ganzzahlen OR
oder AND
Anweisungen der Fall ist . (Ähnlich wie SSE4 ptest
oder SSE ucomiss
: Eingaben in die SIMD-Domäne und Ergebnis in ganzzahligen FLAGS.)
kortestw k1,k1
ist die idiomatische Methode zum Verzweigen von / cmovcc / setcc basierend auf einem AVX512-Vergleichsergebnis, wobei SSE / AVX2 (v)pmovmskb/ps/pd
+ test
oder ersetzt werden cmp
.
Die Verwendung von jz
vs. je
kann verwirrend sein.
jz
und je
sind buchstäblich die gleiche Anweisung , dh der gleiche Opcode im Maschinencode. Sie tun dasselbe, haben aber für den Menschen eine andere semantische Bedeutung . Disassembler (und normalerweise Asm-Ausgaben von Compilern) verwenden immer nur einen, sodass die semantische Unterscheidung verloren geht.
cmp
und sub
setze ZF, wenn ihre zwei Eingänge gleich sind (dh 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 dem Test sagt Ihnen nicht, ob die beiden Operanden gleich waren. Also jz
(Sprung wenn Null) ist das semantisch relevante Synonym.