`testl` eax contre eax?
J'essaie de comprendre un peu de montage.
L'assemblée comme suit, je suis intéressé par la testl
ligne:
000319df 8b4508 movl 0x08(%ebp), %eax
000319e2 8b4004 movl 0x04(%eax), %eax
000319e5 85c0 testl %eax, %eax
000319e7 7407 je 0x000319f0
Je suis en train d'essayer de comprendre ce point de testl
entre %eax
et %eax
? Je pense que les détails de ce que ce code n'est pas important, j'essaie juste de comprendre le test avec lui-même - ne serait pas la valeur de toujours être vrai?
Vous devez vous connecter pour publier un commentaire.
Il teste si
eax
est 0, ou au-dessus ou au-dessous. Dans ce cas, le saut est pris sieax
est de 0.test
etcmp
. Oui, je comprends que c'est votre croyance en fonction de vos commentaires à Cody. Cependant, en le mettant dans mon post, c'est une autre affaire; ce n'est pas une affirmation, je suis prêt à défendre, tout simplement parce que je ne sais pas si elle est identique dans tous les cas.je
,jz
,cmp
, ettest
, et pas de JE, JZ, CMP, ou de TEST. Je suis pointilleux comme ça.test a,a
etcmp $0,a
définir des indicateurs de la même manière; merci de remarquer que c'est un non-trivial de réclamation. re: TEST vstest
: récemment, j'ai commencé à utiliser les majuscules, comme Intel, les manuels de. Mais quand je parle d'AT&T mnémoniques vs Intel mnémoniques, j'utilisetestb
style pour AT&T. IDK si cela vous aide à la lisibilité.Le sens de
test
est pour ET les arguments de l'ensemble, et de vérifier le résultat de zéro. Donc ce code permet de tester si EAX est égal à zéro ou non.je
va sauter si zéro.BTW, ce qui génère une plus petite instruction que
cmp eax, 0
qui est la raison que les compilateurs sera généralement faire de cette façon.L'instruction de test effectue une opération ET logique entre les opérandes, mais ne pas écrire le résultat dans un registre. Seuls les drapeaux sont mis à jour.
Dans votre exemple, le test eax, eax va définir l'indicateur de zéro si eax est égal à zéro, le signe-drapeau si le bit le plus élevé et certaines autres flags.
Le Saut en cas d'Égalité (ej) l'enseignement des sauts si l'indicateur de zéro est réglé.
Vous pouvez traduire le code plus lisible le code comme ceci:
Qui a la même fonctionnalité, mais nécessite quelques octets de plus de code de l'espace. C'est la raison pour laquelle le compilateur émet un test au lieu de comparer.
test eax, eax
etcmp eax, 0
les deux ensemble tous les drapeaux et les mettre en valeurs identiques. Les deux instructions de tous les drapeaux ", selon le résultat". En soustrayant0
ne peut jamais produire de transporter ou de débordement. Votre argument est correct pour l'immédiat, d'autres que 0, mais pas pour 0.test
est commeet
, sauf qu'il n'écrit DRAPEAUX, laissant ses deux entrées non modifiée. Avec deux différents entrées, il est également utile pour tester si quelques morceaux sont toutes à zéro, ou si au moins on est fixé. (par exemple,test al, 3
ensembles ZF si EAX est un multiple de 4 (et donc a la fois de son faible 2 bits à zéro).test eax,eax
jeux de tous les drapeaux exactement de la même manière quecmp eax, 0
serait:a = a&a = a-0
)(Sauf pour le obsolètes (AF auxiliaire-porter le drapeau, utilisé par ASCII/BCD instructions). TEST laisse pas défini, mais CMP définit "selon le résultat". Depuis soustrayant zéro ne peut pas produire un carry à partir de la 4ème à la 5ème peu, le CPM devrait toujours clair AF).
TEST est plus petit (pas dans l'immédiat) et parfois plus rapide (peut macro-fusible dans une comparaison-et-branche uop sur plusieurs Processeurs dans les cas plus que CMP). Que fait
test
le préféré idiome pour tester un registre à zéro ou pas.La seule raison commune pour l'utilisation de la CMP par un 0, c'est quand vous voulez comparer à un opérande mémoire (par exemple,
cmpb $0, (%esi)
à vérifier la terminaison zéro octet à la fin de l'implicite-longueur de C-chaîne de style).AVX512F ajoute
kortestw k1, k2
et AVX512DQ/BW (Skylake, mais pas KNL) ajouterktestb/w/d/q k1, k2
, qui fonctionnent sur la AVX512 masque de registres (k0..k7) mais toujours régulier des DRAPEAUX commetest
ne, de la même façon que entierOR
ouAND
instructions ne.kortestw k1,k1
est le idiomatiques façon de direction /cmovcc /setcc basée sur une AVX512 comparer le résultat, en remplacement de l'ESS/AVX2(v)pmovmskb/ps/pd
+test
oucmp
.Utilisation de
jz
vsje
peut être source de confusion.jz
etje
sont littéralement la même instruction, c'est à dire la même opcode dans le code machine. Ils font la même chose, mais avoir différents sens sémantique pour l'homme. Désassembleurs (et généralement asm sortie de compilateurs) ne jamais utiliser un, de sorte que la distinction sémantique est perdu.cmp
etsub
ensemble ZF lorsque leurs deux entrées sont égales (c'est à dire la soustraction résultat est 0).je
(sauter en cas d'égalité) est sémantiquement pertinents synonyme.test %eax,%eax
/and %eax,%eax
de nouveau ensembles ZF lorsque le résultat est égal à zéro, mais il n'y a pas "d'égalité" test. ZF après le test ne vous dit pas si les deux opérandes sont égaux. Doncjz
(saut si zéro) est le sémantiquement pertinents synonyme.test
être au niveau du bitand
, peut être pas évident pour les gens de l'apprentissage de l'assemblée (et d'être paresseux/pas au courant pour vérifier les instructions du guide de référence de toutes les 60 secondes 😉 🙂 ).kortest*
etktest*
alors que j'étais à elle.Cet extrait de code est issu d'une sous-routine qui est un pointeur vers quelque chose, probablement une structure ou d'un objet. La 2e ligne déréférence le pointeur, la récupération d'une valeur de cette chose - peut-être lui-même un pointeur ou peut-être juste un int, stockées en 2ème membre (offset +4). Les 3e et 4e lignes de tester cette valeur nulle (NULL si c'est un pointeur) et passez les quelques opérations (non illustré) si elle est égale à zéro.
Le test à zéro parfois est codé comme une comparaison immédiate littérale valeur zéro, mais le compilateur (ou de l'homme?) qui a écrit cela pourrait avoir pensé un testl op irait plus vite - tenant compte de tous les modernes CPU trucs comme le pipelining et enregistrer un nouveau nom. C'est à partir de la même sac d'astuces qui détient l'idée de la compensation d'un registre avec XOR EAX,EAX (que j'ai vu sur quelqu'un de la plaque d'immatriculation dans le Colorado!) plutôt que de l'évident, mais peut-être plus lent MOV EAX, #0 (j'utilise un vieux de la notation).
En asm, comme perl, TMTOWTDI.
Si eax est zéro, il va effectuer un saut conditionnel, sinon il va continuer l'exécution à 319e9
Dans certains programmes, ils peuvent être utilisés pour vérifier un dépassement de la mémoire tampon.
Tout en haut de l'espace alloué un 0 est placé. Après la saisie des données dans la pile, il semble pour le 0 au début de l'espace alloué à assurez-vous que l'espace alloué n'est pas débordé.
Il a été utilisé dans la stack0 exercice des exploits-des exercices pour vérifier si il était débordé et si il n'y avait pas et il y avait un zéro, il affiche "Try again"
cmp DWORD PTR [esp+0x5c], 0
/jz 0x8048427 <main+51>
aurait été plus efficace qu'un distinct MOV-charger, puis de TEST. Ce n'est guère une commune de cas d'utilisation pour la vérification du zéro.nous avons pu voir le jg,jle
Si
testl %edx,%edx. jle .L3
nous pourrions facilement trouver jleest le costume(SF^OF)|ZF
,si %edx est zéro ,ZF=1,mais si %edx n'est pas nul et est -1,après la testl ,l'=0,et de la SF =1,de sorte que le flag =true,qui mettent en œuvre sauter.désolé ,mon anglais est pauvre