Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans les listes de cette section, les instructions marquées avec un astérisque (*) sont particulièrement importantes. Les instructions non marquées ne sont pas critiques.
Sur le processeur x86, les instructions sont de taille variable, de sorte que le désassemblage vers l’arrière est un exercice de mise en correspondance de modèle. Pour démonter vers l’arrière d’une adresse, vous devez commencer à désassembler à un point plus loin que vous voulez vraiment aller, puis regarder vers l’avant jusqu’à ce que les instructions commencent à être logiques. Les premières instructions peuvent ne pas être logiques, car vous avez peut-être commencé à désassembler au milieu d’une instruction. Malheureusement, il est possible que le désassemblage ne se synchronise jamais avec le flux d’instructions et que vous devrez essayer de désassembler à un autre point de départ jusqu’à ce que vous trouviez un point de départ qui fonctionne.
For well-packed switch statements, the compiler emits data directly into the code stream, so disassembling through a switch statement will usually stumble across instructions that make no sense (because they are really data). Recherchez la fin des données et continuez à les désassembler.
Notation d’instruction
La notation générale pour les instructions consiste à placer le registre de destination à gauche et la source à droite. Toutefois, il peut y avoir des exceptions à cette règle.
Les instructions arithmétiques sont généralement à deux registres avec les registres source et de destination combinant. Le résultat est stocké dans la destination.
Certaines des instructions ont des versions 16 bits et 32 bits, mais seules les versions 32 bits sont répertoriées ici. Non répertorié ici sont des instructions à virgule flottante, des instructions privilégiées et des instructions utilisées uniquement dans les modèles segmentés (que Microsoft Win32 n’utilise pas).
Pour économiser de l’espace, de nombreuses instructions sont exprimées sous forme combinée, comme illustré dans l’exemple suivant.
* |
MOV |
r1, r/m/#n |
r1 = r/m/#n |
signifie que le premier paramètre doit être un registre, mais que le second peut être un registre, une référence de mémoire ou une valeur immédiate.
Pour économiser encore plus d’espace, les instructions peuvent également être exprimées comme indiqué dans les sections suivantes.
* |
MOV |
r1/m, r/m/#n |
r1/m = r/m/#n |
ce qui signifie que le premier paramètre peut être un registre ou une référence mémoire, et que le second peut être un registre, une référence de mémoire ou une valeur immédiate.
Sauf indication contraire, lorsque cette abréviation est utilisée, vous ne pouvez pas choisir de mémoire pour la source et la destination.
En outre, un suffixe de taille de bits (8, 16, 32) peut être ajouté à la source ou à la destination pour indiquer que le paramètre doit être de cette taille. Par exemple, r8 signifie un registre 8 bits.
Conversion de mémoire, de transfert de données et de données
Les instructions de transfert de mémoire et de données n’affectent pas les indicateurs.
Adresse effective
* |
LEA |
r, m |
Chargez l’adresse effective. (r = adresse de m) |
Par exemple, LEA eax, [esi+4] signifie eax = esi + 4. Cette instruction est souvent utilisée pour effectuer des arithmétiques.
Transfert de données
MOV |
r1/m, r2/m/#n |
r1/m = r/m/#n |
|
MOVSX |
r1, r/m |
Déplacer avec l’extension de signe. |
|
* |
MOVZX |
r1, r/m |
Déplacer avec une extension zéro. |
MOVSX and MOVZX are special versions of the mov instruction that perform sign extension or zero extension from the source to the destination. Il s’agit de la seule instruction qui permet à la source et à la destination d’être de différentes tailles. (Et en fait, elles doivent être différentes tailles.
Manipulation de la pile
The stack is pointed to by the esp register. The value at esp is the top of the stack (most recently pushed, first to be popped); older stack elements reside at higher addresses.
PUSH |
r/m/#n |
Envoyer une valeur sur la pile. |
|
POP |
r/m |
Valeur contextuelle de la pile. |
|
PUSHFD |
Indicateurs push sur la pile. |
||
POPFD |
Indicateurs de fenêtre contextuelle de la pile. |
||
PUSHAD |
Envoyez (push) tous les registres entiers. |
||
POPAD |
Affichez tous les registres entiers. |
||
ENTER |
#n, #n |
Trame de pile de build. |
|
* |
LEAVE |
Découper le cadre de la pile |
The C/C++ compiler does not use the enter instruction. (The enter instruction is used to implement nested procedures in languages like Algol or Pascal.)
The leave instruction is equivalent to:
mov esp, ebp
pop ebp
Conversion de données
CBW |
Convert byte (al) to word (ax). |
CWD |
Convert word (ax) to dword (dx:ax). |
CWDE |
Convert word (ax) to dword (eax). |
CDQ |
convert dword (eax) to qword (edx:eax). |
Toutes les conversions effectuent l’extension de signe.
Manipulation arithmétique et bit
Toutes les instructions arithmétiques et de manipulation de bits modifient les indicateurs.
Arithmétique
ADD |
r1/m, r2/m/#n |
r1/m += r2/m/#n |
|
ADC |
r1/m, r2/m/#n |
r1/m += r2/m/#n + carry |
|
SUB |
r1/m, r2/m/#n |
r1/m -= r2/m/#n |
|
SBB |
r1/m, r2/m/#n |
r1/m -= r2/m/#n + carry |
|
NEG |
r1/m |
r1/m = -r1/m |
|
INC |
r/m |
r/m += 1 |
|
DEC |
r/m |
r/m -= 1 |
|
CMP |
r1/m, r2/m/#n |
Compute r1/m - r2/m/#n |
The cmp instruction computes the subtraction and sets flags according to the result, but throws the result away. It is typically followed by a conditional jump instruction that tests the result of the subtraction.
MUL |
r/m8 |
ax = al * r/m8 |
|
MUL |
r/m16 |
dx:ax = ax * r/m16 |
|
MUL |
r/m32 |
edx:eax = eax * r/m32 |
|
IMUL |
r/m8 |
ax = al * r/m8 |
|
IMUL |
r/m16 |
dx:ax = ax * r/m16 |
|
IMUL |
r/m32 |
edx:eax = eax * r/m32 |
|
IMUL |
r1, r2/m |
r1 *= r2/m |
|
IMUL |
r1, r2/m, #n |
r1 = r2/m * #n |
Multiplication non signée et signée. L’état des indicateurs après la multiplication n’est pas défini.
DIV |
r/m8 |
(ah, al) = (ax % r/m8, ax / r/m8) |
|
DIV |
r/m16 |
(dx, ax) = dx:ax / r/m16 |
|
DIV |
r/m32 |
(edx, eax) = edx:eax / r/m32 |
|
IDIV |
r/m8 |
(ah, al) = ax / r/m8 |
|
IDIV |
r/m16 |
(dx, ax) = dx:ax / r/m16 |
|
IDIV |
r/m32 |
(edx, eax) = edx:eax / r/m32 |
Division non signée et signée. Le premier registre dans l’explication pseudocode reçoit le reste et le second reçoit le quotient. Si le résultat dépasse la destination, une exception de dépassement de capacité de division est générée.
L’état des indicateurs après la division n’est pas défini.
* |
SETcc |
r/m8 |
Set r/m8 to 0 or 1 |
If the condition cc is true, then the 8-bit value is set to 1. Sinon, la valeur 8 bits est définie sur zéro.
Décimale codée en binaire
Vous ne verrez pas ces instructions, sauf si vous déboguez du code écrit dans COBOL.
DAA |
Ajustement décimal après ajout. |
|
DAS |
Ajustement décimal après soustraction. |
These instructions adjust the al register after performing a packed binary-coded decimal operation.
AAA |
Ajustez ASCII après l’ajout. |
AAS |
Ajustez ASCII après soustraction. |
These instructions adjust the al register after performing an unpacked binary-coded decimal operation.
AAM |
Ajustez ASCII après la multiplication. |
AAD |
Ajustez ASCII après la division. |
These instructions adjust the al and ah registers after performing an unpacked binary-coded decimal operation.
Bribes
AND |
r1/m, r2/m/#n |
r1/m = r1/m and r2/m/#n |
|
OR |
r1/m, r2/m/#n |
r1/m = r1/m or r2/m/#n |
|
XOR |
r1/m, r2/m/#n |
r1/m = r1/m xor r2/m/#n |
|
NOT |
r1/m |
r1/m = bitwise not r1/m |
|
* |
TEST |
r1/m, r2/m/#n |
Compute r1/m and r2/m/#n |
The test instruction computes the logical AND operator and sets flags according to the result, but throws the result away. Il est généralement suivi d’une instruction de saut conditionnel qui teste le résultat de l’AND logique.
SHL |
r1/m, cl/#n |
r1/m <<= cl/#n |
|
SHR |
r1/m, cl/#n |
r1/m >>= cl/#n zero-fill |
|
* |
SAR |
r1/m, cl/#n |
r1/m >>= cl/#n sign-fill |
Le dernier bit décalé est placé dans le transport.
SHLD |
r1, r2/m, cl/#n |
Maj vers la gauche double. |
Shift r1 left by cl/#n, filling with the top bits of r2/m. Le dernier bit décalé est placé dans le transport.
SHRD |
r1, r2/m, cl/#n |
Déplacez le double vers la droite. |
Shift r1 right by cl/#n, filling with the bottom bits of r2/m. Le dernier bit décalé est placé dans le transport.
ROL |
r1, cl/#n |
Rotate r1 left by cl/#n. |
ROR |
r1, cl/#n |
Rotate r1 right by cl/#n. |
RCL |
r1, cl/#n |
Rotate r1/C left by cl/#n. |
RCR |
r1, cl/#n |
Rotate r1/C right by cl/#n. |
La rotation est semblable au décalage, sauf que les bits qui sont décalés réapparaît comme les bits de remplissage entrants. La version C des instructions de rotation incorpore le bit de transport dans la rotation.
BT |
r1, r2/#n |
Copy bit r2/#n of r1 into carry. |
BTS |
r1, r2/#n |
Set bit r2/#n of r1, copy previous value into carry. |
BTC |
r1, r2/#n |
Clear bit r2/#n of r1, copy previous value into carry. |
Flux de contrôle
Jcc |
dest |
Branch conditional. |
|
JMP |
dest |
Jump direct. |
|
JMP |
r/m |
Jump indirect. |
|
CALL |
dest |
Call direct. |
|
* |
CALL |
r/m |
Call indirect. |
The call instruction pushes the return address onto the stack then jumps to the destination.
* |
RET |
#n |
Return |
The ret instruction pops and jumps to the return address on the stack. A nonzero #n in the RET instruction indicates that after popping the return address, the value #n should be added to the stack pointer.
LOOP |
Decrement ecx and jump if result is nonzero. |
LOOPZ |
Decrement ecx and jump if result is nonzero and zr was set. |
LOOPNZ |
Decrement ecx and jump if result is nonzero and zr was clear. |
JECXZ |
Jump if ecx is zero. |
Ces instructions sont des vestiges du patrimoine CISC de x86 et, dans les processeurs récents, sont réellement plus lents que les instructions équivalentes écrites de longue date.
Manipulation de chaînes
MOVST |
Move T from esi to edi. |
|
CMPST |
Compare T from esi with edi. |
|
SCAST |
Scan T from edi for accT. |
|
LODST |
Load T from esi into accT. |
|
STOST |
Store T to edi from accT. |
After performing the operation, the source and destination register are incremented or decremented by sizeof(T), according to the setting of the direction flag (up or down).
The instruction can be prefixed by REP to repeat the operation the number of times specified by the ecx register.
The rep mov instruction is used to copy blocks of memory.
The rep stos instruction is used to fill a block of memory with accT.
Drapeaux
LAHF |
Load ah from flags. |
SAHF |
Store ah to flags. |
STC |
Set carry. |
CLC |
Clear carry. |
CMC |
Complement carry. |
STD |
Set direction to down. |
CLD |
Set direction to up. |
STI |
Enable interrupts. |
CLI |
Disable interrupts. |
Instructions interblocées
XCHG |
r1, r/m |
Swap r1 and r/m. |
XADD |
r1, r/m |
Add r1 to r/m, put original value in r1. |
CMPXCHG |
r1, r/m |
Comparer et échanger des conditions. |
The cmpxchg instruction is the atomic version of the following:
cmp accT, r/m
jz match
mov accT, r/m
jmp done
match:
mov r/m, r1
done:
Divers
INT |
#n |
Interceptez le noyau. |
|
BOUND |
r, m |
Trap if r not in range. |
|
* |
NOP |
No operation. |
|
XLATB |
al = [ebx + al] |
||
BSWAP |
r |
Permuter l’ordre d’octet dans l’inscription. |
Here is a special case of the int instruction.
INT |
3 |
Piège de point d’arrêt du débogueur. |
The opcode for INT 3 is 0xCC. The opcode for NOP is 0x90.
Lorsque vous déboguez du code, vous devrez peut-être corriger du code. Pour ce faire, remplacez les octets incriminés par 0x90.
Idiomes
XOR |
r, r |
r = 0 |
|
TEST |
r, r |
Check if r = 0. |
|
* |
ADD |
r, r |
Shift r left by 1. |