Partager via


x86 Instructions

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.