Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V seznamech v této části jsou pokyny označené hvězdičkou (*) zvlášť důležité. Pokyny, které nejsou tak označené, nejsou kritické.
Na procesoru x86 jsou instrukce proměnlivé velikosti, takže zpětné rozebírání je cvičení ve porovnávání vzorů. Chcete-li zpětně rozebrat adresu, měli byste začít rozebírat v okamžiku dalšího zpět, než opravdu chcete, a pak se podívejte dopředu, dokud pokyny začnou dávat smysl. Prvních pár instrukcí nemusí dávat smysl, protože jste možná začali rozebírat uprostřed instrukce. Existuje možnost, bohužel, že demontáž se nikdy nesynchronizuje s instrukčním proudem a budete se muset pokusit rozebrat v jiném počátečním bodě, dokud nenajdete výchozí bod, který funguje.
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). Najděte konec dat a pokračujte v rozebírání dat.
Zápis instrukcí
Obecným zápisem pro pokyny je umístit cílový registr vlevo a zdroj vpravo. Toto pravidlo ale může obsahovat několik výjimek.
Aritmetické instrukce jsou obvykle dvouregistrované ve zdrojovém a cílovém registru, které kombinují. Výsledek se uloží do cíle.
Některé pokyny mají 16bitovou i 32bitovou verzi, ale tady jsou uvedené jenom 32bitové verze. Tady nejsou uvedené pokyny s plovoucí desetinou čárkou, privilegované instrukce a instrukce, které se používají jenom v segmentovaných modelech (které Microsoft Win32 nepoužívá).
Pro úsporu místa se mnoho instrukcí vyjadřuje v kombinované podobě, jak je znázorněno v následujícím příkladu.
* |
MOV |
r1, r/m/#n |
r1 = r/m/#n |
znamená, že první parametr musí být registr, ale druhý může být registr, odkaz na paměť nebo okamžitá hodnota.
Chcete-li ušetřit ještě více místa, lze pokyny vyjádřit také, jak je znázorněno v následujícím příkladu.
* |
MOV |
r1/m, r/m/#n |
r1/m = r/m/#n |
to znamená, že první parametr může být registr nebo odkaz na paměť a druhý může být registr, odkaz na paměť nebo okamžitá hodnota.
Pokud není uvedeno jinak, nelze při použití této zkratky zvolit paměť pro zdroj i cíl.
Příponu bitové velikosti (8, 16, 32) navíc lze připojit ke zdroji nebo cíli, aby bylo možné určit, že parametr musí mít tuto velikost. R8 například znamená 8bitový registr.
Paměť, přenos dat a převod dat
Pokyny k přenosu paměti a dat nemají vliv na příznaky.
Platná adresa
* |
LEA |
r, m |
Načtěte efektivní adresu. (r = adresa m) |
Například LEA eax, [esi+4] znamená eax = esi + 4. Tato instrukce se často používá k provádění aritmetik.
Přenos dat
MOV |
r1/m, r2/m/#n |
r1/m = r/m/#n |
|
MOVSX |
r1, r/m |
Přesunutí s příponou znaménka |
|
* |
MOVZX |
r1, r/m |
Přesunutí s nulovým rozšířením |
MOVSX and MOVZX are special versions of the mov instruction that perform sign extension or zero extension from the source to the destination. Toto je jediná instrukce, která umožňuje zdroji a cíli mít různé velikosti. (A ve skutečnosti musí být různé velikosti.
Manipulace se zásobníkem
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 |
Nasdílení hodnoty do zásobníku |
|
POP |
r/m |
Pop hodnota ze zásobníku |
|
PUSHFD |
Nasdílení příznaků do zásobníku |
||
POPFD |
Pop flags from stack. |
||
PUSHAD |
Odešle všechny celočíselné registry. |
||
POPAD |
Zobrazí všechna celočíselná registru. |
||
ENTER |
#n, #n |
Sestavení rámce zásobníku |
|
* |
LEAVE |
Roztrhání rámu zásobníku |
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
Konverze dat
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). |
Všechny převody provádějí rozšíření znaménka.
Aritmetická a bitová manipulace
Všechny aritmetické a bitové pokyny pro manipulaci upravují příznaky.
Aritmetika
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 |
Násobení bez znaménka a znaménka Stav příznaků po násobení není definován.
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 |
Nepodepsané a podepsané dělení. První registrace v pseudokódovém vysvětlení obdrží zbytek a druhý obdrží podíl. Pokud výsledek přeteče cíl, vygeneruje se výjimka přetečení dělení.
Stav příznaků po dělení není definován.
* |
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. V opačném případě je 8bitová hodnota nastavená na nulu.
Binární kód desetinné číslo
Tyto pokyny se nezobrazí, pokud neladíte kód napsaný v COBOL.
DAA |
Desetinná čárka se upraví po sčítání. |
|
DAS |
Desetinná čárka se upraví po odčítání. |
These instructions adjust the al register after performing a packed binary-coded decimal operation.
AAA |
Po přidání upravte sadu ASCII. |
AAS |
Nastavení ASCII po odčítání |
These instructions adjust the al register after performing an unpacked binary-coded decimal operation.
AAM |
ASCII se upraví po násobení. |
AAD |
ASCII se upraví po dělení. |
These instructions adjust the al and ah registers after performing an unpacked binary-coded decimal operation.
Bity
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. Obvykle následuje podmíněný skok, který testuje výsledek logické funkce 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 |
Poslední bit posunutý ven je umístěn v provedení.
SHLD |
r1, r2/m, cl/#n |
Posun doleva po dvou. |
Shift r1 left by cl/#n, filling with the top bits of r2/m. Poslední bit posunutý ven je umístěn v provedení.
SHRD |
r1, r2/m, cl/#n |
Posunujte doprava dvakrát. |
Shift r1 right by cl/#n, filling with the bottom bits of r2/m. Poslední bit posunutý ven je umístěn v provedení.
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. |
Otočení se podobá posunu, s tím rozdílem, že bity, které jsou posunuty ven, se znovu zobrazí jako příchozí bity výplně. Verze jazyka C pokynů pro otáčení zahrnuje přenosový bit do rotace.
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. |
Tok řízení
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 |
Vratka |
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. |
Tyto instrukce jsou zbytky dědictví CISC x86 a v nedávných procesorech jsou ve skutečnosti pomalejší než ekvivalentní instrukce napsané dlouhou cestou.
Manipulace s řetězci
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.
Vlajky
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. |
Interlocked Instructions
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 |
Porovnání a výměna podmíněného nastavení |
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:
Rozmanitý
INT |
#n |
Přechádět na jádro. |
|
BOUND |
r, m |
Trap if r not in range. |
|
* |
NOP |
No operation. |
|
XLATB |
al = [ebx + al] |
||
BSWAP |
r |
Pořadí bajtů prohození v registru |
Here is a special case of the int instruction.
INT |
3 |
Zarážka ladicího programu |
The opcode for INT 3 is 0xCC. The opcode for NOP is 0x90.
Při ladění kódu možná budete muset opravit nějaký kód. Můžete to udělat tak, že nahradíte bajty, které budou 0x90.
Idiomy
XOR |
r, r |
r = 0 |
|
TEST |
r, r |
Check if r = 0. |
|
* |
ADD |
r, r |
Shift r left by 1. |