Команды сравнения и условные переходы. безусловный переход

ЦИКЛЫ С ПРИМЕНЕНИЕМ АССЕМБЛЕРНЫХ ВСТАВОК

  1. Цикл с постусловием ( эквивалент do{}while)

loop_start: /* начало цикла */ /* вот тут находится тело цикла */ cmpl … /* что-то с чем-то сравнить для принятия ответа о выходе из цикла */ je loop_end /* подобрать соответствующую команду условного перехода для выхода из цикла */ jmp loop_start /* в противном случае повторить цикл опять */loop_end:

  1. Цикл с предусловием (эквивалент while(){})

loop_start: /* начало цикла */ cmpl … /* что-то с чем-то сравнить для принятия ответа о выходе из цикла */ je loop_end /* подобрать соответствующую команду условного перехода для выхода из цикла */ /* вот тут находится тело цикла */ jmp loop_start /* перейти к проверке условия цикла */loop_end:

Команда loop

Синтаксис:

loop метка

Принцип работы:

§ уменьшить значение регистра %ecx на 1;

§ в случае если %ecx = 0, передать управление следующей за loop команде;

§ в случае если %ecx ? 0, передать управление на метку.

Разработаем программу для вычисления суммы чисел от 1 до 10 (конечно же, воспользовавшись формулой суммы арифметической прогрессии, возможно переписать данный код и без цикла — но так как это лишь пример).

Команды сравнения и условные переходы. Абсолютный переход

Команда loop неявно сравнивает регистр %ecx с нулём. Это достаточно удобно для организации циклов, но довольно часто циклы бывают куда сложнее, чем те, что возможно записать при помощиloop. К тому же нужен эквивалент конструкции if(){}. Вот команды, разрешающие делать произвольные сравнения операндов:

cmp операнд_2, операнд_1

Команда cmp делает вычитание операнд_1 – операнд_2 и устанавливает знамёна. Итог вычитания нигде не запоминается.

Сравнили, установили знамёна, — и что дальше? А у нас имеется целое семейство jump-команд, каковые передают управление вторым командам. Эти команды именуются командами условного перехода. Каждой из них поставлено в соответствие условие, которое она контролирует. Синтаксис:

jcc метка

Команды jcc не существует, вместо cc необходимо подставить мнемоническое обозначение условия.

Мнемоника Британское слово Суть Тип операндов
e equal равенство каждые
n not инверсия условия каждые
g greater больше со знаком
l less меньше со знаком
a above больше без символа
b below меньше без символа

Так, je контролирует равенство операндов команды сравнения, jl контролирует условие операнд_1 операнд_2 и без того потом. У каждой команды имеется противоположная: букву n:

§ je — jne: равняется — не равняется;

§ jg — jng: больше — не больше.

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

Команда Состояние контролируемых знамён Условие перехода
JA CF = 0 и ZF = 0 в случае если выше
JAE CF = 0 в случае если выше либо равняется
JB CF = 1 в случае если ниже
JBE CF = 1 либо ZF = 1 в случае если ниже либо равняется
JC CF = 1 в случае если перенос
JE ZF = 1 в случае если равняется
JZ ZF = 1 в случае если 0
JG ZF = 0 и SF = OF в случае если больше
JGE SF = OF в случае если больше либо равняется
JL SF OF в случае если меньше
JLE ZF=1 либо SF OF в случае если меньше либо равняется
JNA CF = 1 и ZF = 1 если не выше
JNAE CF = 1 если не выше либо равняется
JNB CF = 0 если не ниже
JNBE CF=0 и ZF=0 если не ниже либо равняется
JNC CF = 0 в случае если нет переноса
JNE ZF = 0 если не равняется
JNG ZF = 1 либо SF OF если не больше
JNGE SF OF если не больше либо равняется
JNL SF = OF если не меньше
JNLE ZF=0 и SF=OF если не меньше либо равняется
JNO OF=0 в случае если нет переполнения
JNP PF = 0 в случае если количество единичных битов результата нечетно (нечетный паритет)
JNS SF = 0 в случае если символ плюс (знаковый (старший) бит результата равен 0)
JNZ ZF = 0 в случае если нет нуля
JO OF = 1 в случае если переполнение
JP PF = 1 в случае если количество единичных битов результата четно (четный паритет)
JPE PF = 1 то же, что и JP, то имеется четный паритет
JPO PF = 0 то же, что и JNP
JS SF = 1 в случае если символ минус (знаковый (старший) бит результата равен 1)
JZ ZF = 1 в случае если ноль

Логические условия больше и меньше относятся к сравнениям целочисленных значений со знаком, а выше и ниже — к сравнениям целочисленных значений без символа. В случае если пристально взглянуть, то у большинства команд возможно подметить однообразные значения знамён для перехода. Это разъясняется наличием нескольких обстановок, каковые смогут привести к одинаковому состоянию знамён. В этом случае с целью удобства ассемблер допускает пара разных мнемонических обозначений одной и той же машинной команды условного перехода. Эти команды ассемблера по действию полностью равнозначны, поскольку это одинаковая машинная команда. Изначально в процессоре i8086 команды условного перехода имели возможность осуществлять лишь маленькие переходы в пределах -128…+127 байт, считая от следующей команды. Начиная с процессора i386, эти команды уже имели возможность делать каждые переходы в пределах текущего сегмента команд. Это произошло за счет введения в совокупность команд процессора дополнительных машинных команд. Для реализации межсегментных переходов нужно комбинировать команды условного перехода и команду абсолютного перехода jmp. Наряду с этим возможно воспользоваться тем, что фактически все команды условного перехода парные, другими словами имеют команды, контролирующие обратные условия.
Использование jcxz/jecxz:

Команда Состояние знамён в eflags/flags Условие перехода
JCXZ не воздействует в случае если регистр CX=0
JECXZ не воздействует в случае если регистр ECX=0

Команду jcxz/jecxz комфортно применять со всеми командами, применяющими регистр ecx/cx для собственной работы. Это команды организации цикла и цепочечные команды. Крайне важно отметить то, что команда jcxz/jecxz, в отличие от вторых команд перехода, может делать лишь родные переходы в пределах -128…+127 байт, считая от следующей команды. Исходя из этого для нее особенно актуальна неприятность передачи управления потом чем в указанном диапазоне. Для этого возможно привлечь команду абсолютного перехода jmp. К примеру, команду jcxz/jecxz возможно применять для предварительной проверки счетчика цикла в регистре cx для обхода цикла, в случае если его счетчик нулевой.

Не считая команд условного перехода, область применения которых ясна сходу, кроме этого существует команда абсолютного перехода. Эта команда чем-то похожа на оператор goto языка Си. Синтаксис:

jmp адрес

Эта команда передаёт управление на адрес, не контролируя никаких условий. Увидьте, что адрес возможно задан в виде яркого значения (метки), регистра либо обращения к памяти.

Примеры.

  1. Нахождение большого значения в массиве

int max_a (int *a, int n)

{

int i,max=0;

for (i=0;i

{

asm volatile (movl %[Max], %%eax\n

movl %[array], %%ebx\n

cmpl %%eax, %%ebx\n //ebx

jbe less\n

movl %%ebx, %%eax\n

less:\n

movl %%eax,%[output]\n

:[output]=b(max)

: [array]d(a[i]),[Max]b(max)

);

}

return max;

}

  1. Вычисление факториала

int factorial(int n)

{

int res;

asm volatile ( movl %[n], %%ebx\n

movl $1, %%eax\n

loop_start:\n

cmpl $0, %%ebx \n

jne not_zero\n

jmp loop_end\n

not_zero:\n

mull %%ebx\n

sub $1,%%ebx\n

jmp loop_start\n

loop_end:\n

movl %%eax,%[output]\n

:[output]=b(res)

: [n]d(n)

);

return res;

}

Оператор абсолютного перехода


Также читать:

Понравилась статья? Поделиться с друзьями: