2013-02-12 5 views
15

Исправьте меня, если я ошибаюсь.Инструкции по сборке JNZ и CMP

Это мое понимание JNZ и CMP.

JNZ - Скачок будет происходить, если Z флаг не равен нулю (1)

CMP - Если два значения равны, Z флаг установлен (1) в противном случае он не установлен (0)

Olly DBG

Это флэш-учебник я смотрю. Он учит решение простой CrackMe.

Как вы можете видеть, предыдущая инструкция сравнивалась с AL с 47h. Они были равны, чтобы установить флаг Z. (Вы можете видеть это в окнах Регистры с правой стороны)

Следующая инструкция: JNZ. Я понял, что прыжок произойдет, если установлен флаг Z. Установлен флаг Z, но прыжок не состоится!

Почему?

+1

@nrz Ваш комментарий не очень ясен - ожидаемый ОП осознает ошибку, посмотрев на заявление действительно, действительно тяжело? –

+0

@nrz Боже, ты пытаешься запутать меня еще больше?!?! Из других ответов теперь я знаю, что с JNZ скачок происходит только в том случае, если флаг нуля НЕ установлен (0) –

+1

@ 43.52.4D. Извините, я неправильно прочитал предложение «JNZ - прыжок произойдет, если Z-флаг НЕ равен нулю (1)» в вашем вопросе, и в результате мой комментарий был, возможно, запутанным, поэтому я удалил его сейчас. [Быстрая ссылка Intel x86 JUMP] (http://www.unixwiz.net/techtips/x86-jumps.html) содержит полезную таблицу для проверки условий разветвления различных условных переходов x86. – nrz

ответ

24

JNZ сокращен для «Jump if not zero (ZF = 0)» и NOT «Перейти, если ZF установлен».

Если проще запомнить, считайте, что JNZ и JNE (прыжок, если не равный) эквивалентны. Поэтому, когда вы делаете cmp al, 47, а содержимое AL равно 47, ZF установлен, ergo прыжок (если не равен - JNE) не должен приниматься.

11

Здесь я расскажу немного шире.

Там, вообще говоря, два типа условных переходов в x86:

  1. Арифметика прыжки - как JZ (переход, если ноль), JC (переход, если перенос), JNC (переход, если не носить), и т.д. .

  2. Сравнение скачки - JE (скачок, если равны), JB (скачок, если ниже), ЮАЭ (скачок, если выше или равно) и т.д.

Таким образом, использовать первый тип только после арифметики или логические инструкции ли

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 
2

На первый взгляд кажется, будто JNZ означает прыжок, если не ноль (0), как в прыжке, если флаг нуля равен 1 /.

Но на самом деле это означает, что Jump (if) не Zero (установлен).

Если 0 = не установлен и 1 = установлен, то просто помните:
JNZ Прыгает, если нулевой флаг не установлен (0)

0
JNZ  Jump if Not Zero ZF=0 

В самом деле, это заблуждение право.

Чтобы было легче понять, заменить Не нулевой с не указан. (Пожалуйста, обратите внимание, что это для собственного понимания)

Следовательно,

JNZ  Jump if Not Set  ZF=0 

не указан означает флаг Z = 0. Таким образом, прыжок (переход, если не указан)

Set означает флаг Z = 1 Итак, НЕ НАПРАВЛЯЙТЕ