Partilhar via


x86 Instructions

Nas listas desta secção, as instruções marcadas com um asterisco (*) são particularmente importantes. Instruções não tão marcadas não são críticas.

No processador x86, as instruções são de tamanho variável, portanto, desmontar para trás é um exercício de correspondência de padrões. Para desmontar para trás de um endereço, você deve começar a desmontar em um ponto mais para trás do que você realmente quer ir, em seguida, olhar para a frente até que as instruções comecem a fazer sentido. As primeiras instruções podem não fazer qualquer sentido, porque você pode ter começado a desmontar no meio de uma instrução. Existe a possibilidade, infelizmente, de que a desmontagem nunca sincronize com o fluxo de instruções e você terá que tentar desmontar em um ponto de partida diferente até encontrar um ponto 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). Encontre o final dos dados e continue desmontando lá.

Notação de Instrução

A notação geral para instruções é colocar o registro de destino à esquerda e a fonte à direita. No entanto, podem existir algumas exceções a esta regra.

As instruções aritméticas são tipicamente dois registos com os registos de origem e de destino combinados. O resultado é armazenado no destino.

Algumas das instruções têm versões de 16 bits e 32 bits, mas apenas as versões de 32 bits estão listadas aqui. Não estão listadas aqui instruções de ponto flutuante, instruções privilegiadas e instruções que são usadas apenas em modelos segmentados (que o Microsoft Win32 não usa).

Para economizar espaço, muitas das instruções são expressas em forma combinada, como mostrado no exemplo a seguir.

*

MOV

r1, r/m/#n

r1 = r/m/#n

significa que o primeiro parâmetro deve ser um registro, mas o segundo pode ser um registro, uma referência de memória ou um valor imediato.

Para economizar ainda mais espaço, as instruções também podem ser expressas como mostrado a seguir.

*

MOV

r1/m, r/m/#n

r1/m = r/m/#n

o que significa que o primeiro parâmetro pode ser um registro ou uma referência de memória, e o segundo pode ser um registro, referência de memória ou valor imediato.

Salvo indicação em contrário, quando esta abreviatura é usada, não é possível escolher a memória para a origem e o destino.

Além disso, um sufixo de tamanho de bit (8, 16, 32) pode ser anexado à origem ou ao destino para indicar que o parâmetro deve ser desse tamanho. Por exemplo, r8 significa um registro de 8 bits.

Memória, transferência de dados e conversão de dados

As instruções de memória e transferência de dados não afetam os sinalizadores.

Endereço efetivo

*

LEA

r, m

Carregue o endereço efetivo.

(r = endereço de m)

Por exemplo, LEA eax, [esi+4] significa eax = esi + 4. Esta instrução é frequentemente usada para executar aritmética.

Transferência de Dados

MOV

r1/m, r2/m/#n

r1/m = r/m/#n

MOVSX

r1, r/m

Mover com extensão de sinal.

*

MOVZX

r1, r/m

Mover com extensão zero.

MOVSX and MOVZX are special versions of the mov instruction that perform sign extension or zero extension from the source to the destination. Esta é a única instrução que permite que a origem e o destino sejam de tamanhos diferentes. (E, na verdade, eles devem ser de tamanhos diferentes.

Manipulação de pilha

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

Empurre o valor para a pilha.

POP

r/m

Valor pop da pilha.

PUSHFD

Empurre sinalizadores para a pilha.

POPFD

Sinalizadores pop da pilha.

PUSHAD

Empurre todos os registros inteiros.

POPAD

Pop todos os registros inteiros.

ENTER

#n, #n

Crie um quadro de pilha.

*

LEAVE

Derrubar quadro de pilha

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

Conversão de dados

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 as conversões executam a extensão de sinal.

Aritmética e Manipulação de Bits

Todas as instruções aritméticas e de manipulação de bits modificam sinalizadores.

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

Multiplicação não assinada e assinada. O estado das bandeiras após a multiplicação é indefinido.

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

Divisão não assinada e assinada. O primeiro registro na explicação do pseudocódigo recebe o restante e o segundo recebe o quociente. Se o resultado transbordar o destino, uma exceção de estouro de divisão será gerada.

O estado das bandeiras após a divisão é indefinido.

*

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. Caso contrário, o valor de 8 bits é definido como zero.

Decimal codificado binário

Você não verá estas instruções, a menos que esteja depurando o código escrito em COBOL.

DAA

Ajuste decimal após adição.

DAS

Ajuste decimal após subtração.

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

AAA

Ajuste ASCII após adição.

AAS

Ajuste ASCII após subtração.

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

AAM

Ajuste ASCII após a multiplicação.

AAD

ASCII ajustar após a divisão.

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 é seguido por uma instrução de salto condicional que testa o resultado do 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

O último bit deslocado é colocado no transporte.

SHLD

r1, r2/m, cl/#n

Vire para a esquerda duas vezes.

Shift r1 left by cl/#n, filling with the top bits of r2/m. O último bit deslocado é colocado no transporte.

SHRD

r1, r2/m, cl/#n

Mude duas vezes para a direita.

Shift r1 right by cl/#n, filling with the bottom bits of r2/m. O último bit deslocado é colocado no transporte.

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.

A rotação é como o deslocamento, exceto que os bits que são deslocados para fora reaparecem como os bits de preenchimento recebidos. A versão em língua C das instruções de rotação incorpora o bit de transporte na rotação.

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.

Fluxo de controle

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

Devolução

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.

Essas instruções são remanescentes da herança CISC do x86 e, em processadores recentes, são realmente mais lentas do que as instruções equivalentes escritas no longo caminho.

Manipulação de cadeias de caracteres

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.

Bandeiras

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.

Instruções interligadas

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 e troque 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:

Disposições diversas

INT

#n

Armadilha para kernel.

BOUND

r, m

Trap if r not in range.

*

NOP

No operation.

XLATB

al = [ebx + al]

BSWAP

r

Ordem de bytes de troca no registro.

Here is a special case of the int instruction.

INT

3

Armadilha de ponto de interrupção do depurador.

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

Ao depurar o código, talvez seja necessário corrigir algum código. Você pode fazer isso substituindo os bytes ofensivos por 0x90.

Expressões idiomáticas

XOR

r, r

r = 0

TEST

r, r

Check if r = 0.

*

ADD

r, r

Shift r left by 1.