test
est comme and
, sauf qu'il n'écrit que FLAGS, laissant ses deux entrées non modifiées. Avec deux différentes entrées, il est utile de tester si certains bits sont tous zéro, ou si au moins un est défini. (par exemple.test al, 3
définit ZF si EAX est un multiple de 4 (et donc a ses deux bits 2 bas mis à zéro).
test eax,eax
ensembles tous les drapeaux de la même manière que cmp eax, 0
serait:
- CF et DE classer (ET/TEST fait toujours que, et en soustrayant jamais nul produit un report)
- ZF, SF et PF en fonction de la valeur dans EAX. (
a = a&a = a-0
)
(A l'exception du obsolète AF (drapeau auxiliaire carry, utilisé par des instructions ASCII/BCD). TEST leaves it undefined, mais CMP sets it "according to the result". Comme soustraction zéro ne peut pas produire un report du 4 au 5 bit, CMP devrait toujours effacer AF).
TEST est plus petit (pas immédiat) et parfois plus rapide (peut macro-fusible dans une comparaison et branche UOP sur plusieurs unités centrales dans plus de cas que CMP). That makes test
the preferred idiom for testing a register for zero or not. La seule raison courante pour utiliser CMP avec un 0 immédiat est lorsque vous voulez comparer avec un opérande de mémoire (par exemple, cmpb $0, (%esi)
pour vérifier un octet de fin à la fin d'une chaîne de style C de longueur implicite) .
AVX512F ajoute kortestw k1, k2
et AVX512DQ/BW (Skylake mais pas KNL) ajouter ktestb/w/d/q k1, k2
, qui fonctionnent sur les registres de masque (AVX512 de k0..k7), mais encore FLAGS réguliers comme définis test
le fait, de la même façon que nombre entier OR
ou AND
instructions faire.
kortestw k1,k1
est la manière idiomatique à la branche/cmovcc/SetCC basé sur un AVX512 comparer les résultats, en remplaçant SSE/AVX2 (v)pmovmskb/ps/pd
+ test
ou cmp
.
Utilisation de jz
contre je
peut être source de confusion.
jz
and je
are literally the same instruction, c'est-à-dire le même opcode dans le code machine. Ils font la même chose, mais ont une signification sémantique différente pour les humains. Les désassembleurs (et généralement la sortie asm des compilateurs) n'en utiliseront qu'un seul, donc la distinction sémantique est perdue.
cmp
et sub
définissez ZF lorsque leurs deux entrées sont égales (c'est-à-dire que le résultat de la soustraction est 0). je
(saut si égal) est le synonyme sémantiquement pertinent.
test %eax,%eax
/and %eax,%eax
définit à nouveau ZF lorsque le résultat est zéro, mais il n'y a pas de test "d'égalité". ZF après le test ne vous dit pas si les deux opérandes étaient égaux. Donc jz
(sauter si zéro) est le synonyme sémantiquement pertinent.
J'ai fait un montage pour transformer cette réponse populaire en une meilleure réponse canonique à "quoi est-ce que tout cela TEST, et en quoi est-il différent de CMP", qui est en quelque sorte implicite. Voir ma propre réponse plus bas pour des commentaires sur la signification sémantique du JE et JZ synonyme. S'il vous plaît consulter mon édition, car il est assez important, et c'est toujours votre réponse. –
@PeterCordes J'apprécie l'intention, mais je vais revenir à votre édition. 1. Votre «voix» est très différente de la mienne, et en ce moment, elle ressemble beaucoup plus à votre réponse qu'à la mienne. 2. Plus problématique est l'affirmation audacieuse que les drapeaux sortent exactement de la même manière entre 'test' et' cmp'. Oui, je comprends que c'est votre croyance basée sur vos commentaires à Cody. Cependant, le mettre dans mon poste est une question différente; ce n'est pas une affirmation que je suis prêt à accepter, simplement parce que je ne sais pas si c'est identique dans tous les cas. –
@PeterCordes Je comprends le souhait d'avoir une réponse "canonique", mais je pense que votre réponse doit nager ou couler sur ses propres mérites, plutôt que de se greffer sur une réponse acceptée. J'ai dû faire cela pour certaines de mes réponses à des questions très populaires aussi, comme [l'amorce à virgule flottante] (http://stackoverflow.com/a/27030789/13), qui au moment de poster mon réponse déjà eu d'autres réponses avec 500+ upvotes. –