Question

Je lisais l' Intel manuel d'instruction et remarqué qu'il y est un 'NOP' instruction qui ne fait rien sur le PROCESSEUR principal, et un "FNOP' instruction qui ne fait rien sur le FPU.Pourquoi il y a deux instructions distinctes, à ne rien faire?

La seule chose que j'ai vu était qu'ils jettent les différentes exceptions, de sorte que vous pourriez regarder pour une exception de FNOP pour détecter si il y a une FPU disponibles.Mais il n'existe pas d'autres mécanismes comme le CPUID pour le détecter?Ce que la raison pratique est qu'il y ait deux instructions NOP?

Était-ce utile?

La solution

L'expansion de Raymond Chen et Hans Passant de commentaires, il y a des raisons historiques pour qu'il y ait deux instructions distinctes, et pourquoi ils ne l'ont pas tout à fait le même effet.

Aucun des deux instructions, NOP et FNOP, ont été à l'origine conçu comme un explicite pas d'opération de l'instruction.L' NOP l'instruction est en fait juste un alias pour l'instruction XCHG AX,AX.(Ou en mode 32 bits XCHG EAX, EAX.) Sur les premiers processeurs Intel, il n'a pas fait de ne rien faire.Alors qu'il n'avait aucun effet visible de l'extérieur, à l'interne, il a été exécuté comme un XCHG l'instruction, en prenant comme nombre de cycles à exécuter.Le '486 a été le premier PROCESSEUR Intel à traiter spécialement, il pourrait exécuter un NOP en 1 cycle, alors qu'il a fallu 3 cycles pour exécuter tout autre registre à registre XCHG de l'instruction.

Le traitement de l' XCHG AX,AX l'instruction spécialement devient très important dans moderne processeurs Intel.Si elle était encore en fait d'échanger le même registre avec lui-même, qu'il pourrait introduire pipeline étals si une instruction voisine a également utilisé les AX vous inscrire.En les traitant spécialement de la CPU n'a pas de fin à la pensée de l' NOP faut attendre une instruction précédente qui définit AX ou qu'une instruction doit attendre la NOP.

Cela nous amène au fait que il ya beaucoup de différentes instructions qui ne font rien, si XCHG AX,AX c'est la seule qui est un seul octet (comme un cas particulier de la exchange-inscrivez-vous-avec-accumulateur seul octet XCHG les encodages).Souvent, ces instructions sont utilisées comme seule instruction remplacer consécutives NOP instructions, comme lors de l'alignement de début de boucle pour des raisons de performances.Par exemple si vous voulez un 6 octet NOP vous pouvez utiliser LEA EAX,[EAX + 00000000].Intel a finalement ajouté explicite octets plusieurs NOP instruction.(Eh bien, pas tellement ajoutée comme officiellement documenté une instruction qui avait été là depuis le Pentium Pro.) Cependant, seul l'octet forme est spécialement traités;les multiples de l'octet Opr, va générer des stands si proche instructions d'utilisation utiliser les mêmes registres.

Quand AMD a ajouté le support 64 bits pour leurs Processeurs ils sont allés encore plus loin. NOP n'est plus l'équivalent de XCHG EAX,EAX en mode 64 bits.L'un des problèmes avec le jeu d'instructions Intel est qu'il y a beaucoup d'instructions qui ne modifier qu'une partie de vous inscrire.Par exemple MOV BX,AX ne modifie que les 16 bits de EBX en laissant la partie supérieure de 16 bits non modifiée.Ces modifications partielles font qu'il est difficile pour le CPU éviter les stalles, ce AMD décider d'empêcher que lors de l'utilisation de 32 bits instructions en mode 64 bits.Chaque fois que le résultat d'un 32-bit est stocké dans un (64-bit) inscrire, la valeur est zéro, étendue à 64-bits, de sorte que l'ensemble du registre est modifié.Cela signifie XCHG EAX,EAX n'est plus un NOP, car il efface la partie supérieure de 32 bits de EAX (et ainsi, si vous l'écrire explicitement XCHG EAX,EAX, il ne peut pas assembler pour 0x90 et a l'utilisation de la 87 C0 l'encodage).En mode 64 bits NOP est maintenant explicite NOP avec aucune autre interprétation.


Comme pour l' FNOP l'instruction, sur l'original 8087 ce n'est pas tout à fait clair comment la FPU traitée de cette instruction, mais je suis sûr que ce n'était pas traitée comme une explicite pas d'opération de soit.Au moins un vieux Intel manuel, le ASM86 Langue Rerefence Manuel le document que de faire quelque chose sans effet ("les magasins de la pile en haut de la pile en haut").À partir de sa position dans la carte des opcodes, il semble comme il pourrait faire un alias pour FST ST ou FLD ST, qui , tous deux, copiez le haut de la pile vers le haut de la pile.Il n'a toutefois obtenir certains d'un traitement spécial, il a exécuté dans une moyenne de 13 cycles au lieu de la moyenne de 18 ou 20 cycles pour une pile FST ou FLD l'instruction, respectivement.Si elle avait été traitée comme non-instruction d'opération je m'attends qu'il soit encore plus rapide, car il ya un certain nombre de 8087 instructions qui peut s'exécuter dans la moitié du temps.

Plus important encore, les FNOP l'instruction se comporte différemment NOP en raison de la façon dont FPU instructions utilisées pour être mis en œuvre sur des processeurs Intel.Le PROCESSEUR lui-même n'a pas de soutien de l'arithmétique à virgule flottante, au contraire, ces droits ont été déchargées sur une option de coprocesseur à virgule flottante, à l'origine de la 8087.Une des belles choses sur le coprocesseur est qu'il a exécuté les instructions en parallèle avec le CPU.Cependant, cela signifie que le PROCESSEUR doit parfois attendre pour la FPU pour terminer une opération.Le CPU automatiquement attend la fin de l'exécution de l'instruction précédente avant de lui donner une autre instruction, mais d'un programme devra explicitement d'attente (à l'aide d'un WAIT d'instruction), avant de pouvoir lire un résultat que le coprocesseur écrit à la mémoire.

Parce que le coprocesseur ont travaillé en parallèle, cela signifie également que, si une FPU instruction a généré une exception de virgule flottante, par le temps qu'il a détecté ce le CPU serait déjà passé à exécuter l'instruction suivante.Normalement, lorsqu'une instruction génère une exception sur le CPU, il est géré pendant que l'instruction est toujours en cours d'exécution, mais quand un FPU instruction génère une exception de la CPU a déjà terminé l'exécution de cette instruction par la remise à la FPU.Au lieu d'interrompre le PROCESSEUR et la prestation de l'exception de virgule flottante de façon asynchrone, le CPU est averti seulement quand il attend le coprocesseur, que ce soit explicitement ou implicitement.

Dans les processeurs modernes de la FPU n'est plus un coprocesseur, c'est une partie intégrante de la CPU.Cela signifie que les programmes n'ont plus à attendre pour la FPU pour écrire les valeurs de la mémoire.Cependant, la façon la FPU, les exceptions sont gérées n'a pas changé.(Il s'avère que la prestation des exceptions immédiatement est difficile à mettre en œuvre sur les Processeurs modernes donc ils ont pris le parti de le seul cas où ils n'ont pas à le faire.) Donc, si un précédent FPU instruction a généré un non livrés exception de virgule flottante, un NOP quitter l'exception de non distribution, tandis que FNOP, parce que c'est une FPU instruction, va faire un implicite "d'attendre" que les résultats de l'exception de virgule flottante être livré.

Cet exemple illustre la différence:

FLD1       ; push 1.0 onto the FPU stack
FLDZ       ; push 0.0
FDIV       ; divide 1.0 by 0.0
NOP        ; does nothing
NOP        ; does nothing
FNOP       ; signals a FP zero-divide exception and then does nothing
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top