Небольшая шпаргалка по условным и безусловным переходам.
Безусловный переход: выполняется командой JMP <метка>
, может использоваться, как для перехода вперед, пропуская некоторые команды в коде, так и для возврата назад, для повторного выполнения инструкций:
1.
... какой-то код ... JMP label1 ... какой-то код ... label1: ... другой код выполняется после срабатывания инструкции JMP ...
2.
... какой-то код ... labelret: ... какой-то код ... JMP labelret
Условный переход: Выполняется, если выполнено какое-либо условие, переход осуществляется командой Jxx <метка>
, где xx
— мнемоника, указывающая на проверяемое условие.
Инструкция CMP
сравнивает два операнда, в основном вычитая один операнд из другого для сравнения, равны ли операнды или нет, не изменяя целевой или исходный операнд. Инструкция CMP
используется вместе с инструкцией условного перехода для принятия решения. CMP
изменяет регистр флагов, который потом проверяет соответствующая инструкция условного перехода, и осуществляет (не осуществляет) переход по соответствующему адресу (метке).
Синтаксис:
CMP целевой_операнд, исходный_операнд
CMP
сравнивает два числа. В качестве целевого операнда может использоваться значение в регистре или в памяти. Исходный операнд может быть константой (EQU
), непосредственно числом, значением в регистре или памяти. Так же, оба операнда не могут быть одновременно значениями в памяти.
Правильно | Неправильно | Ошибка (MASM) |
cmp eax, ecx | MYVALUE1 dd 2 MYVALUE2 dd 5 … cmp MYVALUE1, MYVALUE2 |
invalid instruction operands |
cmp eax, 0 | cmp 0, eax | immediate operand not allowed |
ERROR_FLAG EQU 16h … cmp eax, ERROR_FLAG |
ERROR_FLAG EQU 16h … cmp ERROR_FLAG, eax |
immediate operand not allowed |
MYVALUE dd ? … cmp eax, MYVALUE |
— | — |
MYVALUE dd ? … cmp MYVALUE, eax |
— | — |
MYVALUE dd ? … cmp MYVALUE, 0 |
MYVALUE dd ? … cmp 0, MYVALUE |
immediate operand not allowed |
MYVALUE dd ? ERROR_FLAG EQU 16h … cmp MYVALUE, ERROR_FLAG |
MYVALUE dd ? ERROR_FLAG EQU 16h … cmp ERROR_FLAG, MYVALUE |
immediate operand not allowed |
— | cmp 0, 1 | immediate operand not allowed |
— | CONST1 equ 1 CONST2 equ 2 … cmp CONST1, CONST2 |
immediate operand not allowed |
Также нужно быть внимательным при сравнении значения в памяти и регистре, если их размерность будет не совпадать, это приведет к ошибке компиляции. Например, при сравнении регистра EAX
, имеющего разрядность двойное слово (DWORD) с переменной, разрядность которой установлена, как байтовая (DB
):
...
MYVALUE db 1
...
cmp eax, MYVALUE
...
;Ошибка: invalid instruction operands
Инструкция | Описание | Проверяемые флаги |
JE/JZ | Если значения равны/Если значение 0 | ZF |
JNE/JNZ | Если значения не равны/Если значение не 0 | ZF |
JG/JNLE | Если больше/Если не меньше или равно | OF SF ZF |
JGE/JNL | Если больше или равно/Если не меньше | OF SF |
JL/JNGE | Если меньше/Если не больше или равно | OF SF |
JLE/JNG | Если меньше или равно/Если не больше | OF SF ZF |
Результаты арифметических операции для беззнаковых чисел или логических операций
Инструкция | Описание | Проверяемые флаги |
JE/JZ | Если значения равны/Если значение 0 | ZF |
JNE/JNZ | Если значения не равны/Если значение не 0 | ZF |
JA/JNBE | Если больше/Если не меньше или равно | CF ZF |
JAE/JNB | Если больше или равно/Если не меньше | CF |
JB/JNAE | Если меньше/Если не больше или равно | CF |
JBE/JNA | Если меньше или равно/Если не больше | AF CF |
Прочие инструкции для условных переходов
Эти инструкции имеют специальное применение и проверяют значения отдельных флагов во флаговом регистре.
Инструкция | Описание | Проверяемые флаги |
JXCZ | Если значение в регистре CX равно 0 | Нет |
JC | Если произошел перенос в результате арифметической операции | CF |
JNC | Перенос не произошел | CF |
JO | Произошло переполнение | OF |
JNO | Переполнение не произошло | OF |
JP/JPE | Число единичных бит четное | PF |
JNP/JPO | Число единичных бит нечетное | PF |
JS | Число со знаком (отрицательное) | SF |
JNS | Число без знака (положительное) | SF |
Ссылки