test
jest jak and
, z wyjątkiem tego, że pisze tylko FLAGI, pozostawiając oba wejścia niezmienione. Dzięki dwóm różnym wejściom przydaje się do testowania, czy niektóre bity mają wartość zero lub czy przynajmniej jeden jest ustawiony. (np. test al, 3
ustawia ZF, jeśli EAX jest wielokrotnością 4 (a zatem ma wyzerowane oba niskie 2 bity).
test eax,eax
ustawia wszystkie flagi dokładnie w taki sam sposób, w cmp eax, 0
jaki :
Z wyjątkiem przestarzałego AF (pomocniczy znacznik przenoszenia, używany w instrukcjach ASCII / BCD). TEST pozostawia go niezdefiniowanym , ale CMP ustawia go „zgodnie z wynikiem” . Ponieważ odejmowanie zera nie może dać przeniesienia z 4 do 5 bitu, CMP powinien zawsze wyczyścić AF.
TEST jest mniejszy (nie jest natychmiastowy) i czasami szybszy (może łączyć się w makro w celu porównania i rozgałęzienia na większej liczbie procesorów w większej liczbie przypadków niż CMP). To jest test
preferowanym idiomem do porównywania rejestru z zerem . Jest to optymalizacja wizjera cmp reg,0
, której można używać niezależnie od znaczenia semantycznego.
Jedynym częstym powodem używania CMP z natychmiastowym 0 jest to, że chcesz porównać z operandem pamięci. Na przykład, cmpb $0, (%esi)
aby sprawdzić kończący bajt zerowy na końcu niejawnej długości ciągu w stylu C.
AVX512F dodajekortestw k1, k2
i AVX512DQ / BW (Skylake-X, ale nie KNL) ktestb/w/d/q k1, k2
, które działają na rejestrach maski AVX512 (k0..k7), ale nadal ustawiają regularne FLAGI, tak jak test
robi to liczba całkowita OR
lub AND
instrukcje. (Coś w rodzaju SSE4 ptest
lub SSE ucomiss
: dane wejściowe w domenie SIMD i dają w wyniku FLAGI całkowite).
kortestw k1,k1
jest idiomatycznym sposobem rozgałęzienia / cmovcc / setcc na podstawie wyniku porównania AVX512, zastępując SSE / AVX2 (v)pmovmskb/ps/pd
+ test
lub cmp
.
Użycie jz
vs. je
może być mylące.
jz
i je
są dosłownie tą samą instrukcją , tj. tym samym kodem operacyjnym w kodzie maszynowym. Robią to samo, ale mają inne znaczenie semantyczne dla ludzi . Dezasemblery (i zazwyczaj dane wyjściowe asm z kompilatorów) będą zawsze używać tylko jednego, więc rozróżnienie semantyczne zostaje utracone.
cmp
i sub
ustawia ZF, gdy ich dwa wejścia są równe (tj. wynik odejmowania wynosi 0). je
(skok, jeśli równe) jest semantycznie istotnym synonimem.
test %eax,%eax
/ and %eax,%eax
ponownie ustawia ZF, gdy wynik jest równy zero, ale nie ma testu „równości”. ZF po teście nie mówi ci, czy dwa operandy były równe. Zatem jz
(skok jeśli zero) jest semantycznie istotnym synonimem.