Команды сравнения и условного перехода

Команды условного перехода осуществляют переход, который выполняется только в случае истинности некоторого условия. Истинность условия проверяется по значениям флагов. Поэтому обычно непосредственно перед командой условного перехода ставится команда сравнения, которая формирует значения флагов:

CMP <операнд1>, <операнд2>

Команда сравнения эквивалентна команде SUB за исключением того, что вычисленная разность никуда не заносится. Назначение команды CMP – установка и сброс флагов.

Что касается команд условного перехода, то их достаточно много, но все они записываются единообразно:

Jxx <метка>

Все команды условного перехода можно разделить на три группы.

В первую группу входят команды, которые обычно ставятся после команды сравнения. В их мнемокодах указывается тот результат сравнения, при котором надо делать переход.

Мнемокод Название Условие перехода после команды CMP op1, op2 Значения флагов Примечание
JE Переход если равно op1 = op2 ZF = 1 Для всех чисел
JNE Переход если не равно op1 ≠ op2 ZF = 0
JL/JNGE Переход если меньше op1 < op2 SF ≠ OF Для чисел со знаком
JLE/JNG Переход если меньше или равно op1 ≤ op2 SF ≠ OF или ZF = 1
JG/JNLE Переход если больше op1 > op2 SF = OF и ZF = 0
JGE/JNL Переход если больше или равно op1 ≥ op2 SF = OF
JB/JNAE Переход если ниже op1 < op2 CF = 1 Для чисел без знака
JBE/JNA Переход если ниже или равно op1 ≤ op2 CF = 1 или ZF = 1
JA/JNBE Переход если выше op1 > op2 CF = 0 и ZF = 0
JAE/JNB Переход если выше или равно op1 ≥ op2 CF = 0

Рассмотрим пример: даны две переменные x и y, в переменную z нужно записать максимальное из чисел x и y.

mov eax, x

cmp eax, y

jge/jae L; Используем JGE для знаковых чисел и JAE – для беззнаковых

mov eax, y

L: mov z, eax

Во вторую группу команд условного перехода входят те, которые обычно ставятся после команд, отличных от команды сравнения, и которые реагируют на то или иное значение какого-либо флага.

Мнемокод Условие перехода Мнемокод Условие перехода
JZ ZF = 1 JNZ ZF = 0
JS SF = 1 JNS SF = 0
JC CF = 1 JNC CF = 0
JO OF = 1 JNO OF = 0
JP PF = 1 JNP PF = 0

Рассмотрим пример: пусть a, b и c – беззнаковые переменные размером 1 байт, требуется вычислить c = a * a + b, но если результат превосходит размер байта, передать управление на метку ERROR.

mov al, a

mul al

jc ERROR

add al, b

jc ERROR

mov c, al

И, наконец, в третью группу входят две команды условного перехода, проверяющие не флаги, а значение регистра ECX или CX:

JCXZ <метка>; Переход, если значение регистра CX равно 0

JECXZ <метка>; Переход, если значение регистра ECX равно 0

Однако эта команда выполняется достаточно долго. Выгоднее провести сравнение с нулём и использовать обычную команду условного перехода.

С помощью команд перехода можно реализовать любые разветвления и циклы.

; if (x > 0) S

cmp x, 0

jle L

...; S

L:

; if (x) S1 else S2

cmp x, 0

je L1

...; S1

jmp L2

L1: ...; S2

L2:

; if (a > 0 && b > 0) S

cmp a, 0

jle L

cmp b, 0

jle L

...; S

L:

; if (a > 0 || b > 0) S

cmp a, 0

jg L1

cmp b, 0

jle L2

L1: ...; S

L2:

; if (a > 0 || b > 0 && c > 0) S

cmp a, 0

jg L1

cmp b, 0

jle L2

cmp c, 0

jle L2

L1: ...; S

L2:

; while (x > 0) do S

L1: cmp x, 0

jle L2

...; S

jmp L1

L2:

; do S while (x > 0)

L: ...; S

cmp x, 0

jg L


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: