Инструкции по сборке JNZ и CMP
Исправьте меня, если я ошибаюсь.
Это мое понимание JNZ
и CMP
.
JNZ
- Переход произойдет, если флаг Z
НЕ равен нулю (1)
CMP
- Если оба значения равны, флаг Z
установлен (1), иначе он не будет установлен (0)
![Olly DBG]()
Это флеш-учебник, который я смотрю. Он учит решение простой CrackMe.
Как вы можете видеть, предыдущая инструкция сравнивала AL
с 47h
. Они были равны, чтобы установить флаг Z
. (Вы можете видеть это в окнах Регистры с правой стороны)
Следующая инструкция: JNZ
. Я понял, что прыжок произойдет, если установлен флаг Z
. Флаг Z
установлен, но переход не выполняется!
Почему?
Ответы
Ответ 1
JNZ является сокращенным для "Jump if not zero (ZF = 0)" и NOT "Перейти, если ZF установлен".
Если легче запомнить, рассмотрим, что JNZ и JNE (скачок, если не равный) эквивалентны. Поэтому, когда вы делаете cmp al, 47
, а содержимое AL
равно 47, ZF задается, ergo прыжок (если не равен - JNE) не должен выполняться.
Ответ 2
Я сделаю здесь немного более широкий ответ.
Как правило, существуют два типа условных переходов в x86:
-
Арифметические прыжки - как JZ (скачок, если ноль), JC (скачок, если перенос), JNC (прыжок, если не переносить) и т.д.
-
Сравнение прыжков - JE (прыжок, если он равен), JB (скачок, если ниже), JAE (прыжок, если выше или равно) и т.д.
Итак, используйте первый тип только после арифметических или логических инструкций:
sub eax, ebx
jnz .result_is_not_zero
and ecx, edx
jz .the_bit_is_not_set
Использовать вторую группу только после инструкций CMP:
cmp eax, ebx
jne .eax_is_not_equal_to_ebx
cmp ecx, edx
ja .ecx_is_above_than_edx
Таким образом, программа становится более читаемой, и вы никогда не будете путать.
Обратите внимание, что иногда эти инструкции являются фактически синонимами. JZ == JE; JC == JB; JNC == JAE и так далее. Ниже приведена полная таблица. Как вы можете видеть, есть только 16 команд условного перехода, но 30 мнемоник - они предусмотрены для создания более читаемого исходного кода:
Mnemonic Condition tested Description
jo OF = 1 overflow
jno OF = 0 not overflow
jc, jb, jnae CF = 1 carry / below / not above nor equal
jnc, jae, jnb CF = 0 not carry / above or equal / not below
je, jz ZF = 1 equal / zero
jne, jnz ZF = 0 not equal / not zero
jbe, jna CF or ZF = 1 below or equal / not above
ja, jnbe CF or ZF = 0 above / not below or equal
js SF = 1 sign
jns SF = 0 not sign
jp, jpe PF = 1 parity / parity even
jnp, jpo PF = 0 not parity / parity odd
jl, jnge SF xor OF = 1 less / not greater nor equal
jge, jnl SF xor OF = 0 greater or equal / not less
jle, jng (SF xor OF) or ZF = 1 less or equal / not greater
jg, jnle (SF xor OF) or ZF = 0 greater / not less nor equal
Ответ 3
Сначала кажется, что JNZ означает прыжок, если не Zero (0), как в прыжке, если флаг нуля равен 1/.
Но на самом деле это означает, что Jump (if) не Zero (установлен).
Если 0 = не задано и 1 = установлено, то просто запомните:
JNZ Выскакивает, если флаг нуля не установлен (0)
Ответ 4
JNZ Jump if Not Zero ZF=0
В самом деле, это путает право.
Чтобы было легче понять, замените Not Zero на Не задано. (Пожалуйста, обратите внимание, что это для вашего понимания)
Следовательно,
JNZ Jump if Not Set ZF=0
Not Set означает флаг Z = 0. Итак, Jump (Jump, если не задано)
Устанавливает флаг Z = 1. Итак, не прыгайте