Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Магда Юрий - Ассемблер для процессоров Intel Pe...rtf
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
564.98 Кб
Скачать

5.1. Условные переходы и ветвления

Организацию ветвлений в программах на ассемблере лучше всего объяснить на примере. В следующем фрагменте программного кода выполняется переход на метку next при равенстве нулю содержимого регистра ЕСХ. Равенство нулю содержимого ЕСХ определяется при помощи команды стр, которая воздействует на флаги AF, CF, OF, PF, SF и ZF:

. . .

cmp ЕСХ, 0

jz next

обработка ситуации, когда ЕСХ не равен О

next:

обработка ситуации, когда ЕСХ равен О

. . .

Если ЕСХ содержит нулевое значение, то команда стр устанавливает флаг нуля ZF в единицу. Команда jz проверяет флаг ZF и, если он равен 1, передает управление на адрес, указанный в ее операнде, то есть на метку next. Фактически данный фрагмент программного кода реализует логическую структуру if, анализирующую условие ЕСХ = 0.

Этот пример демонстрирует один из типичных вариантов организации ветвлений с использованием команды стр. В данном случае эта команда устанавливает или сбрасывает флаг ZF, в зависимости от равенства или неравенства нулю содержимого регистра ЕСХ. Состояние флага анализируется командой jz next, после чего осуществляется переход на одну из двух возможных ветвей программного кода. Большинство команд процессоров Intel воздействуют на флаги, что позволяет задействовать их для организации довольно сложных вычислительных алгоритмов.

Наиболее часто для организации ветвлений используются команды сравнения (cmp, test), a также арифметические (add, sub и др.) и логические команды (and, or, xor). Например, команда test выполняет операцию логического «И» над двумя операндами и в зависимости от результата устанавливает флаги SF, ZF и PF. При этом флаги OF и CF сбрасываются, а флаг AF имеет неопределенное значение. Очень важно то, что команда test не изменяет ни одного из операндов. Ее очень удобно использовать для анализа отдельных битов сравниваемых величин, как в этом примере:

. . .

test AX, 1

jne bitl_set

. . .

Здесь анализируется нулевой бит регистра АХ. Если он установлен в 1, то флаг ZF устанавливается в 0 и выполняется переход на метку bitltest.

Ассемблер поддерживает большое количество команд условного перехода, которые осуществляют передачу управления в зависимости от состояний регистра флагов. При этом следует учитывать некоторые особенности использования таких команд. В подавляющем большинстве случаев команды условных переходов оперируют флагами, установленными в результате сравнения числовых величин. Типы данных, над которыми выполняются арифметические операции и операции сравнения, определяют выбор команд: беззнаковые или знаковые. Типичными примерами беззнаковых данных являются символьные строки, имена, адреса и натуральные числа. Многие числовые значения могут быть как положительными, так и отрицательными.

Например, если регистр АХ содержит 11000110В, а ВХ – 00010110В, то для беззнаковых данных значение в АХ будет больше ВХ, а для знаковых – меньше. Перечень команд условных переходов для беззнаковых данных приведен в табл. 5.1.

Таблица 5.1. Команды условных переходов для чисел без знака

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

Перечень команд условных переходов для знаковых данных приведен в табл. 5.2.

Таблица 5.2. Команды условных переходов для чисел со знаком

Обратите внимание на то, что команды перехода для условий равно или нуль (je/jz) и не равно или не нуль (jne/jnz) присутствуют в обеих таблицах для беззнаковых и знаковых данных. Состояние равно/нуль не зависит от знака числа.

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

Таблица 5.3. Команды условных переходов для специальных проверок

Еще одна команда условного перехода проверяет равенство содержимого регистра СХ нулю. Эта команда необязательно должна располагаться непосредственно за арифметической командой или командой сравнения. Команда jcxz может быть помещена в начало цикла, где она проверяет содержимое регистра СХ.