Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В списках в этом разделе инструкции, помеченные звездочкой (*) особенно важны. Инструкции не так помечены не являются критическими.
На процессоре x86 инструкции имеют переменный размер, поэтому дизассемблирование назад является упражнением в сопоставлении шаблонов. Чтобы дизассемблировать назад от адреса, следует начать дизассемблирование в точке дальше назад, чем вы действительно хотите пойти, а затем с нетерпением ждите, пока инструкции не начнут иметь смысл. Первые несколько инструкций могут не иметь смысла, так как возможно, вы начали дизассемблирование в середине инструкции. Существует возможность, к сожалению, что дизассембли никогда не будет синхронизироваться с потоком инструкций, и вам придется попробовать дизассемблинг в другой начальной точке, пока не найдете начальную точку, которая работает.
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). Найдите конец данных и продолжайте дизассемблинг там.
Нотация инструкций
Общая нотация инструкций заключается в том, чтобы поместить целевой регистр слева и источник справа. Однако в этом правиле могут быть некоторые исключения.
Арифметические инструкции обычно двухрегистрируются с помощью регистров источника и назначения. Результат хранится в месте назначения.
Некоторые инструкции имеют 16-разрядные и 32-разрядные версии, но здесь перечислены только 32-разрядные версии. Здесь не указаны инструкции с плавающей запятой, привилегированные инструкции и инструкции, которые используются только в сегментированных моделях (которые Microsoft Win32 не использует).
Чтобы сэкономить место, многие инструкции выражаются в объединенной форме, как показано в следующем примере.
* |
MOV |
r1, r/m/#n |
r1 = r/m/#n |
означает, что первый параметр должен быть регистром, но второй может быть регистром, ссылкой на память или непосредственным значением.
Чтобы сэкономить еще больше места, инструкции также можно выразить, как показано в следующем примере.
* |
MOV |
r1/m, r/m/#n |
r1/m = r/m/#n |
это означает, что первый параметр может быть регистром или ссылкой на память, а второй — регистром, ссылкой на память или непосредственным значением.
Если не указано иное, если используется это сокращение, нельзя выбрать память как для источника, так и для назначения.
Кроме того, битовый суффикс (8, 16, 32) можно добавить в источник или назначение, чтобы указать, что параметр должен иметь такой размер. Например, r8 означает 8-разрядный регистр.
Преобразование памяти, передачи данных и преобразования данных
Инструкции по передаче памяти и данных не влияют на флаги.
Эффективный адрес
* |
LEA |
r, m |
Загрузка эффективного адреса. (r = адрес m) |
Например , LEA eax, [esi+4] означает eax = esi + 4. Эта инструкция часто используется для арифметики.
Передача данных
MOV |
r1/m, r2/m/#n |
r1/m = r/m/#n |
|
MOVSX |
r1, r/m |
Перемещение с расширением знака. |
|
* |
MOVZX |
r1, r/m |
Перемещение с нулевым расширением. |
MOVSX and MOVZX are special versions of the mov instruction that perform sign extension or zero extension from the source to the destination. Это единственная инструкция, которая позволяет источнику и назначению иметь разные размеры. (И на самом деле они должны быть разными размерами.
Обработка стека
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 |
Отправка значения в стек. |
|
POP |
r/m |
Всплывающее значение из стека. |
|
PUSHFD |
Отправка флагов в стек. |
||
POPFD |
Всплывающие флаги из стека. |
||
PUSHAD |
Отправка всех целых регистров. |
||
POPAD |
Появляется все целые регистры. |
||
ENTER |
#n, #n |
Кадр стека сборки. |
|
* |
LEAVE |
Разрыв кадра стека |
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
Преобразование данных
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). |
Все преобразования выполняют расширение знака.
Арифметические и битовые манипуляции
Все арифметические и битовые инструкции по манипуляции изменяют флаги.
Арифметика
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 |
Незначенный и подписанный умножение. Состояние флагов после умножения не определено.
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 |
Незаписанный и подписанный раздел. Первый регистр в объяснении псевдокода получает оставшуюся часть, а второй получает кворот. Если результат переполняет место назначения, создается исключение переполнения деления.
Состояние флагов после разделения не определено.
* |
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. В противном случае 8-разрядное значение равно нулю.
Двоичный закодированный десятичный знак
Эти инструкции не будут отображаться, если вы не отладите код, написанный в COBOL.
DAA |
Десятичная корректировка после добавления. |
|
DAS |
Десятичная корректировка после вычитания. |
These instructions adjust the al register after performing a packed binary-coded decimal operation.
AAA |
ASCII корректируется после добавления. |
AAS |
ASCII корректируется после вычитания. |
These instructions adjust the al register after performing an unpacked binary-coded decimal operation.
AAM |
ASCII корректируется после умножения. |
AAD |
ASCII корректируется после деления. |
These instructions adjust the al and ah registers after performing an unpacked binary-coded decimal operation.
Биты
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. Обычно за ним следует инструкция условного перехода, которая проверяет результат логического И.
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 |
Последний бит смещен на выноску.
SHLD |
r1, r2/m, cl/#n |
Сдвиг влево. |
Shift r1 left by cl/#n, filling with the top bits of r2/m. Последний бит смещен на выноску.
SHRD |
r1, r2/m, cl/#n |
Сдвиг вправо вправо. |
Shift r1 right by cl/#n, filling with the bottom bits of r2/m. Последний бит смещен на выноску.
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. |
Поворот похож на сдвиг, за исключением того, что биты, которые смещены повторно, появляются как входящие биты заливки. Версия инструкций поворота на языке C включает бит переноса в поворот.
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. |
Поток управления
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. |
Эти инструкции являются остатками наследия CISC x86, и в последних процессорах на самом деле медленнее, чем эквивалентные инструкции, написанные долгий путь.
Обработка строк
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.
Флаги
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. |
Переблокированные инструкции
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 |
Сравнение и обмен условными данными. |
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:
Смешанный
INT |
#n |
Ловушка к ядру. |
|
BOUND |
r, m |
Trap if r not in range. |
|
* |
NOP |
No operation. |
|
XLATB |
al = [ebx + al] |
||
BSWAP |
r |
Переключение порядка байтов в регистре. |
Here is a special case of the int instruction.
INT |
3 |
Ловушка точек останова отладчика. |
The opcode for INT 3 is 0xCC. The opcode for NOP is 0x90.
При отладке кода может потребоваться исправить некоторый код. Это можно сделать, заменив обижающие байты 0x90.
Идиомы
XOR |
r, r |
r = 0 |
|
TEST |
r, r |
Check if r = 0. |
|
* |
ADD |
r, r |
Shift r left by 1. |