Compartir a través de


x86 Instructions

En las listas de esta sección, las instrucciones marcadas con un asterisco (*) son especialmente importantes. Las instrucciones no tan marcadas no son críticas.

En el procesador x86, las instrucciones tienen un tamaño variable, por lo que el desensamblar hacia atrás es un ejercicio de coincidencia de patrones. Para desensamblar hacia atrás desde una dirección, debe empezar a desensamblar en un punto más allá de lo que realmente desea ir y, a continuación, mirar hacia adelante hasta que las instrucciones empiecen a tener sentido. Es posible que las primeras instrucciones no tengan sentido porque es posible que haya empezado a desensamblar en medio de una instrucción. Por desgracia, existe la posibilidad de que el desensamblaje nunca se sincronice con la secuencia de instrucciones y tendrá que intentar desensamblar en un punto de partida diferente hasta que encuentre un punto de partida que funcione.

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). Busque el final de los datos y continúe desensamblando allí.

Notación de instrucción

La notación general de las instrucciones es colocar el registro de destino a la izquierda y el origen a la derecha. Sin embargo, puede haber algunas excepciones a esta regla.

Las instrucciones aritméticas suelen ser dos registros con los registros de origen y destino que combinan. El resultado se almacena en el destino.

Algunas de las instrucciones tienen versiones de 16 y 32 bits, pero solo se enumeran las versiones de 32 bits aquí. Aquí no se muestran instrucciones de punto flotante, instrucciones con privilegios e instrucciones que solo se usan en modelos segmentados (que Microsoft Win32 no usa).

Para ahorrar espacio, muchas de las instrucciones se expresan en forma combinada, como se muestra en el ejemplo siguiente.

*

MOV

r1, r/m/#n

r1 = r/m/#n

significa que el primer parámetro debe ser un registro, pero el segundo puede ser un registro, una referencia de memoria o un valor inmediato.

Para ahorrar aún más espacio, las instrucciones también se pueden expresar como se muestra en lo siguiente.

*

MOV

r1/m, r/m/#n

r1/m = r/m/#n

lo que significa que el primer parámetro puede ser un registro o una referencia de memoria, y el segundo puede ser un registro, una referencia de memoria o un valor inmediato.

A menos que se indique lo contrario, cuando se usa esta abreviatura, no puede elegir la memoria para el origen y el destino.

Además, se puede anexar un sufijo de tamaño de bits (8, 16, 32) al origen o destino para indicar que el parámetro debe tener ese tamaño. Por ejemplo, r8 significa un registro de 8 bits.

Memoria, transferencia de datos y conversión de datos

Las instrucciones de transferencia de datos y memoria no afectan a las marcas.

Dirección efectiva

*

LEA

r, m

Cargue la dirección efectiva.

(r = dirección de m)

Por ejemplo, LEA eax, [esi+4] significa eax = esi + 4. Esta instrucción se usa a menudo para realizar aritmética.

Transferencia de datos

MOV

r1/m, r2/m/#n

r1/m = r/m/#n

MOVSX

r1, r/m

Mover con la extensión de signo.

*

MOVZX

r1, r/m

Mover con una extensión cero.

MOVSX and MOVZX are special versions of the mov instruction that perform sign extension or zero extension from the source to the destination. Esta es la única instrucción que permite que el origen y el destino sean diferentes tamaños. (Y, de hecho, deben ser diferentes tamaños.

Manipulación de pila

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

Insertar valor en la pila.

POP

r/m

Valor pop de la pila.

PUSHFD

Insertar marcas en la pila.

POPFD

Marcas emergentes de la pila.

PUSHAD

Inserte todos los registros enteros.

POPAD

Pop all integer registers.

ENTER

#n, #n

Crear marco de pila.

*

LEAVE

Desmontar marco de pila

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

Conversión de datos

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).

Todas las conversiones realizan la extensión de signo.

Manipulación de bits y aritmética

Todas las instrucciones de manipulación aritmética y bit modifican marcas.

Aritmética

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

Multiplicación sin signo y firmada. El estado de las marcas después de la multiplicación no está definido.

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

División sin signo y firmada. El primer registro de la explicación de pseudocódigo recibe el resto y el segundo recibe el cociente. Si el resultado desborda el destino, se genera una excepción de desbordamiento de división.

El estado de las marcas después de la división no está definido.

*

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. De lo contrario, el valor de 8 bits se establece en cero.

Decimal codificado binario

No verá estas instrucciones a menos que esté depurando el código escrito en COBOL.

DAA

Ajuste decimal después de la adición.

DAS

Ajuste decimal después de la resta.

These instructions adjust the al register after performing a packed binary-coded decimal operation.

AAA

ASCII se ajusta después de la adición.

AAS

Ajuste ASCII después de la resta.

These instructions adjust the al register after performing an unpacked binary-coded decimal operation.

AAM

Ajuste ASCII después de la multiplicación.

AAD

Ajuste ASCII después de la división.

These instructions adjust the al and ah registers after performing an unpacked binary-coded decimal operation.

Bits

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. Normalmente va seguido de una instrucción de salto condicional que comprueba el resultado del AND lógico.

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

El último bit desplazado se coloca en la carga.

SHLD

r1, r2/m, cl/#n

Mayúse doble a la izquierda.

Shift r1 left by cl/#n, filling with the top bits of r2/m. El último bit desplazado se coloca en la carga.

SHRD

r1, r2/m, cl/#n

Cambie el doble a la derecha.

Shift r1 right by cl/#n, filling with the bottom bits of r2/m. El último bit desplazado se coloca en la carga.

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 rotación es como cambiar, excepto que los bits que se desplazan se vuelven a aparecer como los bits de relleno entrantes. La versión del lenguaje C de las instrucciones de rotación incorpora el bit de transporte en la rotación.

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.

Flujo de control

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.

Estas instrucciones son restos del patrimonio CISC de x86 y en procesadores recientes son realmente más lentos que las instrucciones equivalentes escritas a largo plazo.

Manipulación de cadenas

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.

Banderas

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.

Instrucciones interbloqueadas

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

Compare y intercambie condicional.

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:

Misceláneo

INT

#n

Captura al kernel.

BOUND

r, m

Trap if r not in range.

*

NOP

No operation.

XLATB

al = [ebx + al]

BSWAP

r

Cambiar el orden de bytes en el registro.

Here is a special case of the int instruction.

INT

3

Captura de puntos de interrupción del depurador.

The opcode for INT 3 is 0xCC. The opcode for NOP is 0x90.

Al depurar código, es posible que tenga que aplicar revisiones a algún código. Para ello, reemplace los bytes infractores por 0x90.

Idiomas

XOR

r, r

r = 0

TEST

r, r

Check if r = 0.

*

ADD

r, r

Shift r left by 1.