Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11631
Последний выпуск: 19.06.2015

Переходы (прыжки)

Автор: Руслан Аблязов
6 октября 2006 года

Для корректной обработки данных в ассемблере нужна разветвленность программы. Это достигается использованием условных переходов. Условный переход это такая команда процессору, при которой в зависимости от состояния регистра флагов производится передача управления по некоторому адресу иначе говоря прыжок. Этот адрес может быть ближним или дальним. Прыжок считается ближним, если адрес, на который делается прыжок, находится не дальше чем 128 байт назад и 127 байт вперёд от следующей команды. Дальний прыжок это прыжок дальше, чем на [-128,127] байт. Прыгать просто так в любом месте программы бессмысленно. Каждая команда изменяет регистр флагов в зависимости от результата своей операции. Обычно перед командой прыжка идёт команда сравнения, которая изменяет регистр флагов в зависимости от результата. Команд сравнения две: cmp и test. Наиболее универсальная cmp. О команде test я вам расскажу позже. Команда Cmp производит сравнение двух операндов. Она сравнивает два значения (регистр, память, непосредственное значение) и устанавливает флаг нуля Z (zeroflag) если они равны.

	Cmp eax, ebx
	Cmp edx, 045567890h
	Cmp [ebx], esi
	Cmp byte ptr [VALUE1], 045h

Регистр флагов.

Регистр флагов имеет набор флагов, которые устанавливаются или сбрасываются в зависимости от вычислений или других событий. Я не буду расказывать о всех, а только о некоторых важных:

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)) но так как мы не будем их использовать, я не буду о них рассказывать.

Прыжки.

Приведу пример самой распространённой команды условного перехода jz:

Cmp eax, 42h
Jz metka2

Если регистр eax равен 42, то управление передастся первой команде после метки metka2.

Также есть команда безусловного перехода - jmp. Она передаёт управление в любом случае. Вы скажете: "Для этого нужна команда call". Я отвечу: "Команда call пихает в стек адрес возврата, а jmp не трогает стек". Условные переходы могут делать только ближний прыжок, а команда jmp может делать и короткий и дальний прыжки. Вот таблица всех условных переходов.

cmp x, y
ОпкодЗначение(переход,если...)Условие
JAJump if above (X > Y)CF=0 & ZF=0
JAEJump if above or equal (X >= Y)CF=0
JBJump if below (X CF=1
JBEJump if below or equal (X CF=1 or ZF=1
JCJump if carry (cf=1)CF=1
JCXZJump if CX=0регистр CX=0
JE (то же, что и JZ)Jump if equal (X = Y)ZF=1
JGJump if greater (signed) (X > Y)ZF=0 & SF=OF
JGEJump if greater or equal (signed) (X >= Y)SF=OF
JLJump if less (signed) (X SF != OF
JLEJump if less or equal (signed) (X ZF=1 or SF!=OF
JMPБезусловный переход-
JNAJump if not above (X CF=1 or ZF=1
JNAEJump if not above or equal (X CF=1
JNBJump if not below (X >= Y)CF=0
JNBEJump if not below or equal (X > Y)CF=1 & ZF=0
JNCJump if not carry (cf=0)CF=0
JNEJump if not equal (X != Y)ZF=0
JNGJump if not greater (signed) (X ZF=1 or SF!=OF
JNGEJump if not greater or equal (signed) (X SF!=OF
JNLJump if not less (signed) (X >= Y)SF=OF
JNLEJump if not less or equal (signed) (X > Y)ZF=0 & SF=OF
JNOJump if not overflow (signed) (of=0)OF=0
JNPJump if no parity (pf=0)PF=0
JNSJump if not signed (signed) (sf=0)SF=0
JNZJump if not zero (X != Y)ZF=0
JO Jump if overflow (signed) (of=1)OF=1
JPJump if parity (pf=1)PF=1
JPEJump if parity even (PF=1
JPOJump if parity oddPF=0
JSJump if signed (signed)SF=1
JZJump if zero (X = Y)ZF=1

Все команды перехода имеют один операнд: смещение для перехода.

Организация циклов.

Иногда надо организовать цикл, т.е. совершить повторение количество раз, которое указано в регистре ECX. Следовательно, надо у теле цикла уменьшать значение ECX. Именно для этого предназначена команда loop. Он проверяет, равен ли регистр ECX нулю, если он не равен нулю, то значение регистра ECX уменьшается на 1 и совершается ближний прыжок на смещение указанное в операнде.

	Mov ecx, 023h
repeat:
	::..; обязательно ближнее расстояние
	Loop repeat	

Тело цикла выполнится 23h раза.

Команда loope делает то же самое, но перед прыжком проверяет, установлен ли флаг ZF, если он установлен, то прыжок совершается. Точно тоже самое делает команда loopz. Команды loopne и loopnz делают то же сомое что и loope, но прыгают, если флаг ZF сброшен.

С переходами разобрались. Разобрались не только с переходами, но и с циклами. Продолжаем изучение ассемблера, читаем следующий урок.


Назад | Оглавление | Далее

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог