Инструкции по сборке 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. Итак, не прыгайте