Udostępnij przez


x86 Instructions

Na listach w tej sekcji szczególnie ważne są instrukcje oznaczone gwiazdką (*). Instrukcje nie są tak oznaczone, że nie są krytyczne.

Na procesorze x86 instrukcje są zmienne, więc dezasemblowanie do tyłu jest ćwiczeniem w dopasowywaniu wzorca. Aby dezasemblować do tyłu od adresu, należy zacząć dezasemblować w pewnym momencie dalej niż naprawdę chcesz iść, a następnie czekać, aż instrukcje rozpoczną sens. Pierwsze instrukcje mogą nie mieć sensu, ponieważ być może rozpoczęto dezasemblowanie w środku instrukcji. Istnieje możliwość, niestety, że dezasemblacja nigdy nie będzie synchronizowana ze strumieniem instrukcji i trzeba będzie spróbować dezasemblować w innym punkcie wyjścia, dopóki nie znajdziesz punktu początkowego, który działa.

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). Znajdź koniec danych i kontynuuj dezasemblowanie.

Notacja instrukcji

Ogólna notacja instrukcji polega na umieszczaniu rejestru docelowego po lewej stronie i źródle po prawej stronie. Mogą jednak istnieć pewne wyjątki od tej reguły.

Instrukcje arytmetyczne są zwykle dwuestrowe z połączonymi rejestrami źródłowymi i docelowymi. Wynik jest przechowywany w miejscu docelowym.

Niektóre instrukcje mają wersje 16-bitowe i 32-bitowe, ale w tym miejscu są wymienione tylko wersje 32-bitowe. Nie wymieniono tutaj instrukcji zmiennoprzecinkowych, instrukcji uprzywilejowanych i instrukcji, które są używane tylko w modelach segmentowanych (których platforma Microsoft Win32 nie używa).

Aby zaoszczędzić miejsce, wiele instrukcji jest wyrażonych w postaci połączonej, jak pokazano w poniższym przykładzie.

*

MOV

r1, r/m/#n

r1 = r/m/#n

oznacza, że pierwszy parametr musi być rejestrem, ale drugi może być rejestrem, odwołaniem do pamięci lub natychmiastową wartością.

Aby zaoszczędzić jeszcze więcej miejsca, instrukcje można również wyrazić, jak pokazano poniżej.

*

MOV

r1/m, r/m/#n

r1/m = r/m/#n

oznacza to, że pierwszy parametr może być rejestrem lub odwołaniem do pamięci, a drugi może być rejestrem, odwołaniem do pamięci lub wartością natychmiastową.

O ile nie określono inaczej, jeśli ten skrót jest używany, nie można wybrać pamięci zarówno dla źródła, jak i miejsca docelowego.

Ponadto sufiks rozmiaru bitowego (8, 16, 32) można dołączyć do źródła lub miejsca docelowego, aby wskazać, że parametr musi mieć ten rozmiar. Na przykład r8 oznacza rejestr 8-bitowy.

Pamięć, transfer danych i konwersja danych

Instrukcje dotyczące pamięci i transferu danych nie mają wpływu na flagi.

Obowiązujący adres

*

LEA

r, m

Efektywny adres ładowania.

(r = adres m)

Na przykład eax LEA, [esi+4] oznacza eax = esi + 4. Ta instrukcja jest często używana do wykonywania arytmetyki.

Transfer danych

MOV

r1/m, r2/m/#n

r1/m = r/m/#n

MOVSX

r1, r/m

Przenieś z rozszerzeniem podpisywania.

*

MOVZX

r1, r/m

Przenieś z rozszerzeniem zerowym.

MOVSX and MOVZX are special versions of the mov instruction that perform sign extension or zero extension from the source to the destination. Jest to jedyna instrukcja, która zezwala na różne rozmiary źródła i miejsca docelowego. (I w rzeczywistości muszą być różne rozmiary.

Manipulowanie stosem

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

Wypchnij wartość na stos.

punkt obecności

r/m

Wartość pop ze stosu.

PUSHFD

Wypychanie flag na stos.

POPFD

Wyskakujące flagi ze stosu.

PUSHAD

Wypchnij wszystkie rejestry liczb całkowitych.

POPAD

Pokaż wszystkie rejestry liczb całkowitych.

ENTER

#n, #n

Kompiluj ramkę stosu.

*

LEAVE

Rozerwanie ramki stosu

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

Konwersja danych

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

Wszystkie konwersje wykonują rozszerzenie podpisywania.

Arytmetyka i manipulowanie bitami

Wszystkie instrukcje arytmetyczne i bitowe modyfikują flagi.

Arytmetyka

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

Niepodpisane i podpisane mnożenie. Stan flag po mnożenie jest niezdefiniowany.

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

Niepodpisane i podpisane dzielenie. Pierwszy rejestr w wyjaśnieniu pseudokodu otrzymuje resztę, a drugi otrzymuje iloraz. Jeśli wynik przepełni miejsce docelowe, zostanie wygenerowany wyjątek przepełnienia podziału.

Stan flag po dzieleniu jest niezdefiniowany.

*

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. W przeciwnym razie wartość 8-bitowa jest ustawiona na zero.

Liczba dziesiętna kodowana binarnie

Te instrukcje nie będą widoczne, chyba że debugujesz kod napisany w aplikacji COBOL.

DAA

Dopasuj wartość dziesiętną po dodaniu.

DAS

Dostosowywanie dziesiętne po odejmaniu.

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

AAA

Dostosowywanie ASCII po dodaniu.

AAS

Dostosowywanie ASCII po odejmaniu.

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

AAM

Dostosowywanie ASCII po mnożenia.

AAD

ASCII dopasowuje się po dzieleniu.

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

Bitów

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. Zazwyczaj następuje instrukcje skoku warunkowego, które testuje wynik logiczny AND.

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

Ostatni bit przesunięty jest umieszczony w przewożeniu.

SHLD

r1, r2/m, cl/#n

Przesuń w lewo w lewo.

Shift r1 left by cl/#n, filling with the top bits of r2/m. Ostatni bit przesunięty jest umieszczony w przewożeniu.

SHRD

r1, r2/m, cl/#n

Przesuń w prawo dwukrotnie.

Shift r1 right by cl/#n, filling with the bottom bits of r2/m. Ostatni bit przesunięty jest umieszczony w przewożeniu.

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.

Rotacja jest jak przesunięcie, z tą różnicą, że bity, które są przesuwane ponownie jako przychodzące bity wypełnienia. Wersja języka C instrukcji rotacji zawiera bit przenoszenia do obrotu.

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.

Przepływ sterowania

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

Zwrot

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.

Te instrukcje są pozostałościami dziedzictwa CISC x86 i w ostatnich procesorach są rzeczywiście wolniejsze niż równoważne instrukcje zapisane długą drogę.

Manipulowanie ciągami

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.

Flagi

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.

Instrukcje z blokadą

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

Porównanie i wymiana warunkowa.

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:

Rozmaity

INT

#n

Pułapka do jądra.

BOUND

r, m

Trap if r not in range.

*

NOP

No operation.

XLATB

al = [ebx + al]

BSWAP

r

Zamień kolejność bajtów w rejestrze.

Here is a special case of the int instruction.

INT

3

Pułapka punktu przerwania debugera.

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

Podczas debugowania kodu może być konieczne stosowanie poprawek kodu. Można to zrobić, zastępując bajty obrażające 0x90.

Idiomów

XOR

r, r

r = 0

TEST

r, r

Check if r = 0.

*

ADD

r, r

Shift r left by 1.