Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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. |