Assembleur 80x86 | IMUL |
---|---|
INTEL 8088+ | Multiplication entière |
Syntaxe
IMUL Opérande | INTEL 8088+ |
IMUL dest, src | INTEL 80286+ |
IMUL dest, src, imm | INTEL 80386+ |
Description
Cette instruction permet d'effectuer une multiplication signée (nombre entier). Le multiplicateur est implicite; il est ajusté en fonction de la taille de la base. Le produit est toujours plus grand que le multiplicateur. Le type de multiplication détermine quel registre l'instruction utilisera :
Taille | Base | Multiplicateur | Résultat |
---|---|---|---|
Octet | AL | Opérande | AX |
Mot | AX | Opérande | DX:AX |
Double mot | EAX | Opérande | EDX:EAX |
Remarques
- L'instruction IMUL effectue une multiplication signée de deux opérandes. Cette instruction a 3 formats, selon le nombre d'opérandes : Format à un opérande - Cette forme est identique à celle utilisée par l'instruction MUL. Ici, l'opérande source (dans un registre à usage général ou un emplacement de mémoire) est multiplié par la valeur dans le registre AL, AX, EAX ou RAX (selon la taille de l'opérande) et le produit (deux fois la taille de l'opérande d'entrée) est entreposé dans les registres AX, DX:AX, EDX:EAX ou RDX:RAX, respectivement. Format à deux opérandes - Avec ce format, l'opérande de destination (le premier opérande) est multiplié par l'opérande source (deuxième opérande). L'opérande de destination est un registre à usage général et l'opérande source est une valeur immédiate, un registre à usage général ou un emplacement de mémoire. Le produit intermédiaire (deux fois la taille de l'opérande d'entrée) est tronqué et entreposé à l'emplacement de l'opérande de destination. Format à trois opérandes - Ce format nécessite un opérande de destination (le premier opérande) et deux opérandes source (les deuxième et troisième opérandes). Ici, le premier opérande source (pouvant être un registre à usage général ou un emplacement de mémoire) est multiplié par le second opérande source (une valeur immédiate). Le produit intermédiaire (deux fois la taille du premier opérande source) est tronqué et entreposé dans l'opérande de destination (un registre à usage général).
- Lorsqu'une valeur immédiate est utilisée comme opérande, elle est étendue par signe jusqu'à la longueur du format d'opérande de destination.
- Les drapeaux CF et OF sont définis lorsque la valeur entière signée du produit intermédiaire diffère du produit tronqué de taille d'opérande étendue de signe, sinon les drapeaux CF et OF sont effacés.
- Les trois formats de l'instruction IMUL sont similaires en ce que la longueur du produit est calculée à deux fois la longueur des opérandes. Avec le formulaire à un opérande, le produit est entreposé exactement dans la destination. Avec les formats à 2 et 3 opérandes, cependant, le résultat est tronqué à la longueur de la destination avant d'être entreposé dans le registre de destination. En raison de cette troncature, le drapeau CF ou OF doit être testé pour s'assurer qu'aucun bit significatif n'est pas perdu.
- Les formats à 2 et 3 opérandes peuvent également être utilisés avec des opérandes non signés car la moitié inférieure du produit est la même, que les opérandes soient signés ou non signés. Cependant, les drapeaux CF et OF ne peuvent pas être utilisés pour déterminer si la moitié supérieure du résultat est non nulle.
- En mode 64 bits, la taille d'opération 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. L'utilisation de REX.W modifie les 3 formats de l'instruction comme suit. Format à un opérande - L'opérande source (dans un registre à usage général 64 bits ou un emplacement de mémoire) est multiplié par la valeur dans le registre RAX et le produit est entreposé dans les registres RDX:RAX. Format à deux opérandes - L'opérande source est promu à 64 bits s'il s'agit d'un registre ou d'un emplacement de mémoire. L'opérande de destination est promu à 64 bits. Format à trois opérandes - Le premier opérande source (un registre ou un emplacement de mémoire) et l'opérande de destination sont promus à 64 bits. Si l'opérande source est une valeur immédiate, son signe est étendu à 64 bits.
Algorithme
MODULE IMUL(Opérande|dest,src) SI Nombre d'opérande = 1 ALORS SI Taille de l'opérande en bits = 8 ALORS AX ← AL x Opérande SI (AH = 00h) OU (AH = FFh) ALORS CF ← 0 OF ← 0 SINON CF ← 1 OF ← 1 FIN SI SINON SI Taille de l'opérande en bits = 16 ALORS DX:AX ← AX x Opérande SI (DX = 0000h) OU (DX = FFFFh) ALORS CF ← 0 OF ← 0 SINON CF ← 1 OF ← 1 FIN SI SINON EDX:EAX ← EAX x Opérande SI ((EDX = 00000000h) OU (EDX = FFFFFFFFh)) ALORS CF ← 0 OF ← 0 SINON CF ← 1 OF ← 1 FIN SI FIN SI SINON SI Nombre d'opérande = 2 ALORS temp ← dest x src dest ← dest x src SI temp = dest ALORS CF ← 1 OF ← 1 SINON CF ← 0 OF ← 0 FIN SI SINON temp ← dest x src dest ← dest x src SI temp = dest ALORS CF ← 1 OF ← 1 SINON CF ← 0 OF ← 0 FIN SI FIN SI FIN SI |
Mnémonique
Instruction | Opcode | Description |
---|---|---|
IMUL reg/mem8 | F6h /5 | Multiplie le contenu du registre AL avec une opérande mémoire ou registre de 8 bits et met le résultat entier dans le registre AX. |
IMUL reg/mem16 | F7h /5 | Multiplie le contenu du registre AX avec une opérande mémoire ou registre de 16 bits et met le résultat entier dans le registre DX:AX. |
IMUL reg/mem32 | F7h /5 | Multiplie le contenu du registre EAX avec une opérande mémoire ou registre de 32 bits et met le résultat entier dans le registre EDX:EAX. |
IMUL reg/mem64 | F7h /5 | Multiplie le contenu du registre RAX avec une opérande mémoire ou registre de 64 bits et met le résultat entier dans le registre RDX:RAX. |
IMUL reg16, reg/mem16 | 0Fh AFh /r | Multiplie le contenu d'un registre de destination 16 bits avec une opérande mémoire ou registre de 16 bits et met le résultat entier dans le registre de destination 16 bits. |
IMUL reg32, reg/mem32 | 0Fh AFh /r | Multiplie le contenu d'un registre de destination 32 bits avec une opérande mémoire ou registre de 32 bits et met le résultat entier dans le registre de destination 32 bits. |
IMUL reg64, reg/mem64 | 0Fh AFh /r | Multiplie le contenu d'un registre de destination 64 bits avec une opérande mémoire ou registre de 64 bits et met le résultat entier dans le registre de destination 64 bits. |
IMUL reg16, reg/mem16, imm8 | 6Bh /r ib | Multiplie le contenu d'une opérande mémoire ou registre de 16 bits par une valeur entière immédiate de 8 bits et met le résultat entier dans le registre 16 bits. |
IMUL reg32, reg/mem32, imm8 | 6Bh /r ib | Multiplie le contenu d'une opérande mémoire ou registre de 32 bits par une valeur entière immédiate de 8 bits et met le résultat entier dans le registre 32 bits. |
IMUL reg64, reg/mem64, imm8 | 6Bh /r ib | Multiplie le contenu d'une opérande mémoire ou registre de 64 bits par une valeur entière immédiate de 8 bits et met le résultat entier dans le registre 64 bits. |
IMUL reg16, reg/mem16,imm16 | 69h /r iw | Multiplie le contenu d'une opérande mémoire ou registre de 16 bits par une valeur entière immédiate de 16 bits et met le résultat entier dans le registre 16 bits. |
IMUL reg32, reg/mem32,imm32 | 69h /r id | Multiplie le contenu d'une opérande mémoire ou registre de 32 bits par une valeur entière immédiate de 32 bits et met le résultat entier dans le registre 32 bits. |
IMUL reg64, reg/mem64,imm32 | 69h /r id | Multiplie le contenu d'une opérande mémoire ou registre de 64 bits par une valeur entière immédiate de 32 bits et met le résultat entier dans le registre 64 bits. |
Cycles d'horloge
Opérande | Cycle d'horloge | Taille en octets | |||
---|---|---|---|---|---|
8086 | 80286 | 80386 | 80486 | ||
reg8 | 80 à 98 | 13 | 9 à 14 | 13 à 18 | 2 |
reg16 | 128 à 154 | 21 | 9 à 22 | 13 à 26 | 2 |
reg32 | - | - | 9 à 38 | 12 à 42 | 2 |
mem8 | 86 à 104 | 16 | 12 à 17 | 13 à 18 | 2 à 4 |
mem16 | 134 à 160 | 24 | 12 à 25 | 13 à 26 | 2 à 4 |
mem32 | - | - | 12 à 41 | 13 à 42 | 2 à 4 |
reg16,reg16 | - | - | 9 à 22 | 13 à 26 | 3 à 5 |
reg32,reg32 | - | - | 9 à 38 | 13 à 42 | 3 à 5 |
reg16,mem16 | - | - | 12 à 25 | 13 à 26 | 3 à 5 |
reg16,immed | - | 21 | 9 à 22 | 13 à 26 | 3 |
reg32,immed | - | 21 | 9 à 38 | 13 à 42 | 3 à 6 |
reg16,reg16,immed | - | 2 | 9 à 22 | 13 à 26 | 3 à 6 |
reg32,reg32,immed | - | 21 | 9 à 38 | 13 à 42 | 3 à 6 |
reg16,mem16,immed | - | 24 | 12 à 25 | 13 à 26 | 3 à 6 |
reg32,mem32,immed | - | 24 | 12 à 41 | 13 à 42 | 3 à 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é | |
#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 | Un segment de données nulle est utilisé comme référence mémoire | |||
#PF(Faute de page) | X | X | Une faute de page résultat de l'exécution de l'instruction | |
#SS(Pile non-canonique) | X | X | X | Une adresse mémoire dépasse la limite du segment de pile ou n'est pas canonique |
Exemples
L'exemple suivant permet de multiplier AX par AX et de mettre le résultat dans le registre DX et le registre AX :
- IMUL AX
Voici un exemple en Turbo Pascal montrant une utilisation de cet instruction :
- Program AsmIMul;
-
- Var a,b,c,c_:Integer;
-
- Function IMul(X,Y:Integer):LongInt;Assembler;ASM
- MOV AX,X
- IMUL Y
- END;
-
- BEGIN
- a := 1;
- b := 2;
- c := 3;
- c_ := -3;
- WriteLn('0 * 0 : ',IMul(0,0));
- WriteLn('0 * 1 : ',IMul(0,1));
- WriteLn('1 * 1 : ',IMul(1,1));
- WriteLn('1 * 2 : ',IMul(1,2));
- WriteLn('a * b : ',IMul(a,b));
- WriteLn('a * b * c : ',IMul(Mul(a,b),c));
- WriteLn('a * b * c_ : ',Integer(IMul(IMul(a,b),c_)));
- WriteLn('c * c_ : ',Integer(IMul(c,c_)));
- WriteLn('a * b * 20 : ',IMul(IMul(a,b),20));
- END.
on obtiendra le résultat suivant :
0 * 0 : 00 * 1 : 0
1 * 1 : 1
1 * 2 : 2
a * b : 2
a * b * c : 6
a * b * c_ : -6
c * c_ : -9
a * b * 20 : 40
Voir également
Langage de programmation - Assembleur 80x86 - Lexique et dictionnaire d'instruction assembleur 80x86 - Instruction IDIV
Langage de programmation - Assembleur 80x86 - Lexique et dictionnaire d'instruction assembleur 80x86 - Instruction MUL
Langage de programmation - Mathématique - Multiplication russe (Multiplication par décalage de bits)
Références
Le livre d'Or PC, Martin Althaus, 1992, ISBN: 2-7361-0934-1, page 812
Assembleur Facile, Philippe Mercier, 1990, ISBN: 2-501-01176-7, page 405
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 115.
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 563 à 567.