Условные переходы
Win32Asm Tutorial |
назад | 7- Условные переходы | вперед |
7.0 - Условные переходы
В секции кода, вы также можете использовать метки, как здесь:
.code
mov eax, edx
sub eax, ecx
cmp eax, 2
jz loc1
xor eax, eax
jmp loc2
loc1:
xor eax, eax
inc eax
loc2:
(xor eax, eax означает: eax = 0.)
Давайте исследуем код:
mov eax, edx : поместить edx в eax
sub eax, ecx : вычесть ecx из eax
cmp eax, 2
Это новая команда: cmp. Команда Cmp производит сравнение двух операндов. Она сравнивает два значения (регист, память, непосредственное значение) и устанавливает флаг нуля Z (zeroflag) если они равны. Флаг нуля, так же, как флаг переноса, находится во внутреннем флаговом регистре.
jz loc1
Это также новая команда - условный переход. Jz = (jump if zero) переход если ноль. То есть переход, если флаг нуля установлен. Loc1 это метка для смещения в памяти, на команды 'xor eax, eax | inc eax'. Значит jz loc1 = переход на команды после метки loc1 если флаг нуля установлен.
cmp eax, 2 : устанавливает флаг нуля, если eax=2
jz loc1 : переход, если флаг нуля установлен
=
Переход на команды после метки loc1, если eax равно 2
Далее здесь стоит jmp loc2. Это тоже переход, но безусловный: т.е. всегда переходит. Что именно делает вышеприведенный код:
if ((edx-ecx)==2)
{
eax = 1;
}
else
{
eax = 0;
}
или BASIC версия:
IF (edx-ecx)=2 THEN
EAX = 1
ELSE
EAX = 0
END IF
7.1 - Регистр флагов
Регистр флага имеет набор флагов, которые устанавливаются или сбрасываются в зависимости от вычислений или других событий. Я не буду расказывать о всех, а только о некоторых важных:
ZF (Zero flag) Флаг нуля
Этот флаг устанавливается, когда результат вычисления нулевой (чтобы сравнить - фактически substraction без того, чтобы сохранить(экономить) результаты, но устанавливать флажки только). This flag is set when the result of a calculation is zero (сравнение это фактически вычитание без сохранения результата, и установка соответствующих флагов).
SF (Sign flag) Флаг знака
Если установлен, значит результат вычисления - отрицательное число.
CF (Carry flag) Флаг переноса
Флаг переноса, содержит крайний левый (старший) бит после вычислений.
OF (Overflow flag) Флаг переполнения
Указывает переполнение результата вычисления, т.е. результат больше, приемник.
Есть еще большое колличество флагов (флаг паритета (pf), вспомогательный флаг переноса (af), флаг трассировки (tf), флаг прерывания (if), флаг управления (df), флаг уровня привилегий ввода/вывода (iopl) , флаг вложенности задачи (nt), флаг возобновления (rf), флаг виртуального режима (vm)) но так как мы не будем их использовать, я не буду о них рассказывать.
7.2 - Переходы
Существует целая серия условных переходов и все они переходят в зависимости от состояния флагов. Поскольку большинство переходов имеют четкие названия, вам даже не нужно знать какие флаги должны быть установлены. "Jump if greater or equal" "переход если больше или равно" (jge) например тоже самое, что "Флаг знака = Флагу переполнения", а "Jump if zero" "Переход если нуль" (JZ) тоже самое, что "Переход, если флаг нуля = 1 (JZ)".
В таблице, 'Значение' показывает каким должен быть результат вычисления, чтобы произошел переход.
Опкод | Значение(переход,если...) | Условие |
JA | Jump if above (X > Y) | CF=0 & ZF=0 |
JAE | Jump if above or equal (X >= Y) | CF=0 |
JB | Jump if below (X < Y) | CF=1 |
JBE | Jump if below or equal (X < Y) | CF=1 or ZF=1 |
JC | Jump if carry (cf=1) | CF=1 |
JCXZ | Jump if CX=0 | регистр CX=0 |
JE (то же, что и JZ) | Jump if equal (X = Y) | ZF=1 |
JG | Jump if greater (signed) (X > Y) | ZF=0 & SF=OF |
JGE | Jump if greater or equal (signed) (X >= Y) | SF=OF |
JL | Jump if less (signed) (X < Y) | SF != OF |
JLE | Jump if less or equal (signed) (X <= Y) | ZF=1 or SF!=OF |
JMP | Безусловный переход | - |
JNA | Jump if not above (X <= Y) | CF=1 or ZF=1 |
JNAE | Jump if not above or equal (X < Y) | CF=1 |
JNB | Jump if not below (X >= Y) | CF=0 |
JNBE | Jump if not below or equal (X > Y) | CF=1 & ZF=0 |
JNC | Jump if not carry (cf=0) | CF=0 |
JNE | Jump if not equal (X != Y) | ZF=0 |
JNG | Jump if not greater (signed) (X <= Y) | ZF=1 or SF!=OF |
JNGE | Jump if not greater or equal (signed) (X < Y) | SF!=OF |
JNL | Jump if not less (signed) (X >= Y) | SF=OF |
JNLE | Jump if not less or equal (signed) (X > Y) | ZF=0 & SF=OF |
JNO | Jump if not overflow (signed) (of=0) | OF=0 |
JNP | Jump if no parity (pf=0) | PF=0 |
JNS | Jump if not signed (signed) (sf=0) | SF=0 |
JNZ | Jump if not zero (X != Y) | ZF=0 |
JO | Jump if overflow (signed) (of=1) | OF=1 |
JP | Jump if parity (pf=1) | PF=1 |
JPE | Jump if parity even ( | PF=1 |
JPO | Jump if parity odd | PF=0 |
JS | Jump if signed (signed) | SF=1 |
JZ | Jump if zero (X = Y) | ZF=1 |
Все команды перехода имеют один операнд: смещение для перехода.
[наверх]