Assembleur 80x86 | MOV |
---|---|
INTEL 8088+, x86-64 | MOVe |
Syntaxe
MOV opérandecible,opérandesource |
Paramètres
Nom | Description |
---|---|
opérandecible | Ce paramètre permet d'indiquer l'opérande recevant la valeur. L'opérande peut être un registre ou une adresse mémoire si l'autre opérande n'est pas déjà une adresse mémoire ou un uniquement un registre mémoire si l'autre opérande est une adresse mémoire. |
opérandesource | Ce paramètre permet d'indiquer l'opérande contenant la valeur à copier. L'opérande peut être un registre ou une adresse mémoire si l'autre opérande n'est pas déjà une adresse mémoire ou un uniquement un registre mémoire si l'autre opérande est une adresse mémoire. |
Description
Cette instruction permet de copier opérande source dans une opérande destinataire (opérande cible). L'opérande source peut être une valeur immédiate, un registre à usage général, un registre de segment ou un emplacement de mémoire. Le registre de destination peut être un registre à usage général, un registre de segment (CS, DS, ES, FS, GS et SS) ou un emplacement de mémoire. Les deux opérandes doivent être de la même taille, ce qui peut être un octet, un mot, un double mot ou un quadruple mot.
Remarques
- L'instruction MOV ne peut pas être utilisée pour charger le registre CS. Si cette situation se produit, vous aurez une exception d'opcode invalide (#UD). Pour charger le registre CS, vous devez utilisez les instructions JMP, CALL ou RET.
- Si l'opérande de destination est un registre de segment (DS, ES, FS, GS ou SS), l'opérande source doit être un sélecteur de segment valide. En mode protégé, le déplacement d'un sélecteur de segment dans un registre de segment entraîne automatiquement le chargement des informations de descripteur de segment associées à ce sélecteur dans la partie cachée du registre de segment. Lors du chargement de ces informations, les informations de sélecteur de segment et de descripteur de segment sont validées Les données de descripteur de segment sont obtenues à partir de l'entrée GDT ou LDT pour le sélecteur de segment spécifié.
- Un sélecteur de segment NULL (soit des valeurs de 0000h à 0003h) peut être chargé dans les registres DS, ES, FS et GS sans provoquer d'exception de protection. Cependant, toute tentative ultérieure de référencer un segment dont le registre de segment correspondant est chargé avec une valeur NULL entraîne une exception de protection générale (#GP) et aucune référence de mémoire ne se produit.
- Le chargement du registre SS avec une instruction MOV supprime ou inhibe certaines exceptions de débogage et inhibe les interruptions sur la limite d'instruction suivante. (L'inhibition se termine après l'envoi d'une exception ou l'exécution de l'instruction suivante.) Ce comportement permet de charger un pointeur de pile dans le registre ESP avec l'instruction suivante («MOV ESP,valeur du pointeur de pile») avant qu'un événement puisse être remis.
- Lors de l'exécution de l'instruction «MOV Reg, Sreg», le microprocesseur copie le contenu de Sreg dans les 16 bits les moins significatifs du registre à usage général. Les bits supérieurs du registre de destination (registre cible) sont nuls pour la plupart des microprocesseurs IA-32 (processeurs Pentium Pro et ultérieurs) et pour tous les microprocesseurs supportant le Intel 64, à l'exception des bits de 31 à 16 n'étant pas définis pour les microprocesseurs Intel Quark X1000, Pentium et les microprocesseurs antérieurs.
- En mode 64 bits, la taille de fonctionnement par défaut de l'instruction est de 32 bits. L'utilisation du préfixe REX.R permet d'accéder à des registres supplémentaires (R8 à R15). L'utilisation du préfixe REX.W favorise le fonctionnement à 64 bits.
Algorithme
MODULE MOV(opérandecible,opérandesource) opérandecible ← opérandesource |
Mnémonique
Instruction | Opcode | Description |
---|---|---|
MOV reg/mem8, reg8 | 88h /r | Copie le contenu du registre 8 bits dans l'opérande de registre ou mémoire 8 bits. |
MOV reg/mem16, reg16 | 89h /r | Copie le contenu du registre 16 bits dans l'opérande de registre ou mémoire 16 bits. |
MOV reg/mem32, reg32 | 89h /r | Copie le contenu du registre 32 bits dans l'opérande de registre ou mémoire 32 bits. |
MOV reg/mem64, reg64 | 89h /r | Copie le contenu du registre 64 bits dans l'opérande de registre ou mémoire 64 bits. |
MOV reg8, reg/mem8 | 8Ah /r | Copie le contenu de l'opérande de registre ou mémoire 8 bits dans le registre 8 bits. |
MOV reg16, reg/mem16 | 8Bh /r | Copie le contenu de l'opérande de registre ou mémoire 16 bits dans le registre 16 bits. |
MOV reg32, reg/mem32 | 8Bh /r | Copie le contenu de l'opérande de registre ou mémoire 32 bits dans le registre 32 bits. |
MOV reg64, reg/mem64 | 8Bh /r | Copie le contenu de l'opérande de registre ou mémoire 64 bits dans le registre 64 bits. |
MOV reg16/32/64/mem16,segReg | 8Ch /r | Copie le contenu du registre de segment dans l'opérande de registre ou mémoire 16, 32 ou 64 bits. |
MOV segReg, reg/mem16 | 8Eh /r | Copie le contenu de l'opérande de registre ou mémoire 16 bits dans le registre de segment. |
MOV AL,[xxh] | A0h xxh | Copie le contenu de l'opérande de l'adresse mémoire 8 bits dans le registre AL. |
MOV AX, [yyxxh] | A1h xxh yyh | Copie le contenu de l'opérande de l'adresse mémoire 16 bits dans le registre AX. |
MOV EAX, moffset32 | A1h dw | Copie le contenu de l'opérande de l'adresse mémoire 32 bits dans le registre EAX. |
MOV RAX, moffset64 | A1h dw | Copie le contenu de l'opérande de l'adresse mémoire 64 bits dans le registre RAX. |
MOV moffset8, AL | A2h dw | Copie le registre AL dans l'opérande de l'adresse mémoire 8 bits. |
MOV moffset16, AX | A3h dw | Copie le registre AX dans l'opérande de l'adresse mémoire 16 bits. |
MOV moffset32, EAX | A3h dw | Copie le registre EAX dans l'opérande de l'adresse mémoire 32 bits. |
MOV moffset64, RAX | A3h dw | Copie le registre RAX dans l'opérande de l'adresse mémoire 64 bits. |
MOV reg8, imm8 | (B0h+rb) ib | Copie une valeur immédiate de 8 bits dans un registre 8 bits. |
MOV reg16, imm16 | (B8h+rw) iw | Copie une valeur immédiate de 16 bits dans un registre 16 bits. |
MOV reg32, imm32 | (B8h+rd) id | Copie une valeur immédiate de 32 bits dans un registre 32 bits. |
MOV reg64, imm64 | (B8h+rq) iq | Copie une valeur immédiate de 64 bits dans un registre 64 bits. |
MOV reg/mem8, imm8 | C6h /0 ib | Copie une valeur immédiate 8 bits dans une opérande de registre ou mémoire 8 bits. |
MOV reg/mem16, imm16 | C7h /0 iw | Copie une valeur immédiate 16 bits dans une opérande de registre ou mémoire 16 bits. |
MOV reg/mem32, imm32 | C7h /0 id | Copie une valeur immédiate 32 bits dans une opérande de registre ou mémoire 32 bits. |
MOV reg/mem64, imm32 | C7h /0 id | Copie une valeur immédiate 32 bits dans une opérande de registre ou mémoire 64 bits. |
MOV CRn, reg32 | 0Fh 22h /r | Copie un registre 32 bits dans un registre CRn. |
MOV CRn, reg64 | 0Fh 22h /r | Copie un registre 64 bits dans un registre CRn. |
MOV reg32, CRn | 0Fh 20h /r | Copie un registre CRn dans un registre 32 bits. |
MOV reg64, CRn | 0Fh 20h /r | Copie un registre CRn dans un registre 64 bits. |
MOV CR8, reg32 | F0h 0Fh 22h/r | Copie un registre 32 bits dans le registre CR8. |
MOV CR8, reg64 | F0h 0Fh 22h/r | Copie un registre 64 bits dans le registre CR8. |
MOV reg32, CR8 | F0h 0Fh 20h/r | Copie un registre CR8 dans le registre 32 bits. |
MOV reg64, CR8 | F0h 0Fh 20h/r | Copie un registre CR8 dans le registre 64 bits. |
MOV reg32, DRn | 0Fh 21h /r | Copie un registre DRn dans le registre 32 bits. |
MOV reg64, DRn | 0Fh 21h /r | Copie un registre DRn dans le registre 64 bits. |
MOV DRn, reg32 | 0Fh 23h /r | Copie un registre 32 bits dans le registre DRn. |
MOV DRn, reg64 | 0Fh 23h /r | Copie un registre 64 bits dans le registre DRn. |
Cycles d'horloge
Opérande | Cycle d'horloge | Taille en octets | |||
---|---|---|---|---|---|
8086 | 80286 | 80386 | 80486 | ||
reg,reg | 2 | 2 | 2 | 1 | 2 |
mem,reg | 9+EA | 3 | 2 | 1 | 2 à 4 |
reg,mem | 8+EA | 5 | 4 | 1 | 2 à 4 |
mem,immed | 10+EA | 3 | 2 | 1 | 3 à 6 |
reg,immed | 4 | 2 | 2 | 1 | 2 à 4 |
mem,accum | 10 | 3 | 2 | 1 | 3 |
accum,mem | 10 | 5 | 4 | 1 | 3 |
segreg,reg16 | 2 | 2 | 2 | 3 | 2 |
segreg,mem16 | 8+EA | 5 | 5 | 9 | 2 à 4 |
reg16,segreg | 2 | 2 | 2 | 3 | 2 |
mem16,segreg | 9+EA | 3 | 2 | 3 | 2 à 4 |
reg32,CR0/CR2/CR3 | - | - | 6 | 4 | |
CR0,reg32 | - | - | 10 | 16 | |
CR2,reg32 | - | - | 4 | 4 | 3 |
CR2,reg32 | - | - | 5 | 4 | 3 |
reg32,DR0/DR1/DR2/DR3 | - | - | 22 | 10 | 3 |
reg32,DR6/DR7 | - | - | 22 | 10 | 3 |
DR0/DR1/DR2/DR3,reg32 | - | - | 22 | 11 | 3 |
DR6/DR7,reg32 | - | - | 16 | 11 | 3 |
reg32,TR6/TR7 | - | - | 12 | 4 | 3 |
TR6/TR7,reg32 | - | - | 12 | 4 | 3 |
reg32,TR3 | - | - | - | 3 | |
TR3,reg32 | - | - | - | 6 |
Exceptions
Message | Mode réel | Virtuel 8086 | Mode protégé | Description |
---|---|---|---|---|
#AC(Vérifie l'alignement) | X | X | Un désalignement de la référence mémoire est effectué quand une vérification d'alignement est activé | |
#DB(Déboguage) | X | X | Un registre de déboguage est référencé quand une détection générale du bit GD du registre DR7 est fixé. | |
#GP(Protection général) | X | X | X | Une adresse mémoire dépasse la limite du segment de données ou n'est pas canonique |
X | L'opérande de destination n'est pas dans un segment non écrivable | |||
X | Un segment de données nulle est utilisé comme référence mémoire | |||
X | X | Le CPL ne vaut pas 0. | ||
X | La valeur 1 est écrite dans n'importe quel des 32 bits haut du registre DR6 ou DR7 en mode 64 bits. | |||
X | X | Une tentative de fixer le CR0.PG = 1 et le CR0.PE = 0. | ||
X | X | Une tentative de fixer le CR0.CD = 0 et le CR0.NW = 1. | ||
X | X | Bits réservé à 1 dans le pointeur de la table de page de répertoire (utilise le mode «legacy» d'adresse physique étendue) et l'instruction modifie le registre CR0, CR3 ou CR4. | ||
X | X | Une tentative d'écrire 1 dans n'importe quel bit réservé du registre CR0, CR3, CR4 ou CR8. | ||
X | X | Une tentative de fixé le CR0.PG en mode long est activé (EFER.LME = 1), mais l'adresse d'extensions de page est désactivé (CR4.PAE = 0). | ||
X | Une tentative d'effacer le CR4.PAE en mode «long» est activé (EFER.LMA = 1). | |||
#GP(Sélecteur) | X | Un registre de segment est chargé, mais le descripteur de segment dépasse la limite de la table du descripteur. | ||
X | Un registre de segment est chargé et le bit TI de sélecteur de segment est fixé, mais le sélecteur LDT est un sélecteur nulle. | |||
X | Le registre SS est chargé avec un sélecteur de segment nulle dans un mode non 64 bits ou avec CPL = 3. | |||
X | Le registre SS est chargé et le sélecteur de segment RPL et le descripteur de segment DPL n'est pas égale au CPL. | |||
X | Le registre SS est chargé et le segment pointe dans un segment de données non écrivable. | |||
X | Le registre DS, ES, FS ou GS est chargé et le segment pointe sur des données ou un segment de code non-conforme, mais le RPL ou CPL est supérieur au DPL. | |||
X | Le registre DS, ES, FS ou GS est chargé et le segment ne pointe pas sur un segment de données ou un segment de code en lecture. | |||
#NP(Sélecteur) | X | Le registre DS, ES, FS ou GS n'est pas chargé avec une valeur non-nulle. | ||
#PF(Faute de page) | X | X | Une faute de page résultat de l'exécution de l'instruction | |
#SS(Pile) | X | X | X | Une adresse mémoire dépasse la limite du segment de pile ou n'est pas canonique |
#SS(Sélecteur) | X | X | X | Le registre SS est chargé avec un sélecteur non-nulle et le segment est marqué non présent. |
#UD(Opcode invalide) | X | Une tentative de chargement dans le registre CS. | ||
X | X | Le registre DR4 ou DR5 est référencé quand le bit d'extensions de déboguage (DE) du registre CR4 est fixé. | ||
X | Un registre de déboguage illégale (DR8 à DR15) est référencé. | |||
#UD(Instruction invalide) | X | X | X | Un registre de contrôle illégale est référencé (CR1, CR6 à CR7, CR8 à CR15). |
X | X | X | L'utilisation d'un préfixe de verrou LOCK en lecture du registre CR8 n'est pas supporté, comme indiqué par le bit 4 du registre ECX de la fonction 8000_0001h de l'instruction CPUID. |
Bonnes pratiques
Lorsque vous fixez la valeur 0 à un registre de microprocesseur, comme AX, BX, CX, DX, SI, DI, EAX, EBX, ECX, EDX, ESI, EDI, RAX, RBX, RCX, RDX, RSI, RDI, vous ne devriez pas utiliser l'instruction «MOV» si vous n'avez pas de drapeau de comparaison à conserver. Ainsi, l'instruction suivant occupera 2 octets :
- ; Bonne pratique
- XOR EAX,EAX
Plutôt que 6 octets dans le cas suivant :
- ; Mauvaise pratique
- MOV EAX,0
Et vous aurez le même résultat.
Exemples
L'exemple suivant permet de copier la valeur du registre EBX dans le registre EAX :
- MOV EAX,EBX
L'exemple suivant permet de copier la valeur 5 dans un octet de l'emplacement mémoire de VARIABLE :
- MOV Byte Ptr [VARIABLE],5
L'exemple suivant permet de fixer la valeur 1 dans une emplacement mémoire spécifié par l'adresse [BX] de la taille d'un octet, la valeur 2 d'un emplacement mémoire spécifié par l'adresse [SI] de la taille d'un mot et la valeur 3 d'un emplacement mémoire spécifié par l'adresse [DI] de la taille d'un double mot :
L'exemple suivant permet de retourner la taille de la mémoire conventionnelle dans le registre AX s'il fonctionne en mode réel sous une architecture IBM PC :
Voici quelques exemples typiques de l'utilisation de cette instruction :
- .MODEL small
- .STACK 100h
- .DATA
- Message1 DB 'MOV AX,15 = ','$'
- Message2 DB 'MOV BX,16 = ','$'
- CRLF DB 13,10,'$'
- .CODE
- PrintDigit PROC NEAR
- OR AX,AX
- JNS Positif
- PUSH AX
- MOV AH,02h
- MOV DL,'-'
- INT 21h
- POP AX
- NEG AX
- Positif:
- MOV BX,10
- XOR CX,CX
- NextDigit:
- XOR DX,DX
- DIV BX
- PUSH DX
- INC CX
- OR AX,AX
- JNZ NextDigit
- PrintOneDigit:
- POP AX
- ADD AL,48
- MOV DL,AL
- MOV AH,02h
- INT 21h
- LOOP PrintOneDigit
- RET
- ENDP
-
- .startup
- MOV AX,@data
- MOV DS,AX
- MOV AH,9
- MOV DX,OFFSET Message1
- INT 21h
- MOV AX,15
- CALL PrintDigit
- MOV AH,9
- MOV DX,OFFSET CRLF
- INT 21h
-
- MOV AX,@data
- MOV DS,AX
- MOV AH,9
- MOV DX,OFFSET Message2
- INT 21h
- MOV BX,16
- XCHG AX,BX
- CALL PrintDigit
- MOV AH,9
- MOV DX,OFFSET CRLF
- INT 21h
-
- MOV AX,4C00h
- INT 21h
- END
on obtiendra le résultat suivant :
MOV AX,15 = 15MOV BX,16 = 16
Voir également
Instruction assembleur 80x86 - Instruction CLTS
Instruction assembleur 80x86 - Instruction LMSW
Instruction assembleur 80x86 - Instruction MOVD
Instruction assembleur 80x86 - Instruction MOVSX
Instruction assembleur 80x86 - Instruction MOVZX
Instruction assembleur 80x86 - Instruction MOVSXD
Instruction assembleur 80x86 - Instruction MOVS
Instruction assembleur 80x86 - Instruction SMSW
Références
Le livre d'Or PC, Martin Althaus, 1992, ISBN: 2-7361-0934-1, page 820
Assembleur Facile, Philippe Mercier, 1990, ISBN: 2-501-01176-7, page 411
AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions, Edition Advanced Micro Devices, Revision 3.14, September 2007, Publication No. 24594, page 156.
Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2A: Instruction Set Reference, A-M, Edition Intel, Mars 2010, Publication No. 253666-034US, page 713 à 724.