Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
74
Добавлен:
20.05.2015
Размер:
297.98 Кб
Скачать

3. Классификация команд передачи управления

Принятие решения о том, какая команда должна выполняться следующей может быть:

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

условным — решение о том, какая команда должна выполняться следующей, принимается на основе анализа некоторых условий или данных.

То, какая команда программы должна выполняться следующей, процессор узнает по содержимому пары регистров CS:(E)IP, в которой:

CS — регистр сегмента кода, в котором находится физический (базовый) адрес текущего сегмента кода;

EIP/IP — регистр указателя команды, в котором находится значение, представляющее собой смещение в памяти следующей выполняемой команды относительно начала текущего сегмента кода.

Таким образом, команды передачи управления изменяют содержимое регистров CS и EIP, в результате чего процессор выбирает для выполнения не следующую по порядку команду программы, а команду в некотором другом участке программы. Конвейер внутри процессора при этом сбрасывается.

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

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

безусловного перехода;

вызова процедуры и возврата из процедуры;

вызова программных прерываний и возврата из программных прерываний.

Команды условной передачи управления:

перехода по результату команды сравнения;

перехода по состоянию определенного флага;

перехода по содержимому регистра ЕСХ/СХ.

Команды управления циклом:

организации цикла со счетчиком ЕСХ/СХ;

организации цикла со счетчиком ЕСХ/СХ с возможностью досрочного выхода из цикла по дополнительному условию.

Решение о том, куда необходимо передать управление в языке ассемблера осуществляется с помощью меток. Метка — это символическое имя, обозначающее определенную ячейку памяти и предназначенное для использования в качестве операнда в командах передачи управления.

Подобно переменной, транслятор ассемблера присваивает любой метке три атрибута:

имя сегмента кода, где эта метка описана;

смещение – расстояние в байтах от начала сегмента кода, в котором описана метка;

тип, или атрибут расстояния, метки.

Последний атрибут может принимать два значения:

near — переход на метку возможен только в пределах сегмента кода;

far — переход на метку возможен только в результате межсегментной передачи управления.

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

Транслятор ассемблера обеспечивает две возможности работы с этим счетчиком:

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

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

Безусловные переходы

Команды перехода модифицируют регистр указателя команды EIP/IP и, возможно, сегментный регистр кода CS. Что именно должно подвергнуться модификации, зависит:

от типа операнда в команде безусловного перехода (ближний или дальний);

от модификатора, который указывается перед адресом перехода в команде перехода и может принимать следующие значения (сам адрес при прямом переходе находится непосредственно в команде, а при косвенном — в регистре или ячейке памяти):

NEAR PTR — прямой переход на метку внутри текущего сегмента кода, при этом модифицируется только регистр EIP/IP (в зависимости от заданного типа сегмента кода use16 или use32) на основе указанного в команде адреса (метки) или выражения, использующего символ извлечения значения счетчика адреса команд ($);

FAR PTR — прямой переход на метку в другом сегменте кода, при этом адрес перехода задается в виде непосредственного операнда или адреса (метки) и состоит из 16-разрядного селектора и 16/32-разрядного смещения, которые загружаются, соответственно, в регистры CS и EIP/IP;

WORD PTR — косвенный переход на метку внутри текущего сегмента кода, при этом модифицируется (значением смещения размером 16 или 32 бита из памяти по указанному в команде адресу или из регистра) только регистр EIP/IP;

DWORD PTR — косвенный переход на метку в другом сегменте кода, при этом модифицируются (значением из памяти — и только из памяти, из регистра нельзя) оба регистра, CS и EIP/IP (первое слово/двойное слово адреса перехода, представляющее собой смещение, загружается в EIP/IP; второе/третье слово — в CS).

Синтаксис команды безусловного перехода без сохранения информации о точке возврата:

jmp [модификатор] адрес_перехода

Здесь адрес_перехода представляет метку или адрес области памяти, в которой находится указатель перехода.

Всего в системе команд процессора есть несколько кодов машинных команд безусловного перехода JMP. Их различия определяются дальностью перехода и способом задания целевого адреса. Дальность перехода определяется местоположением операнда адрес_перехода. Этот адрес может находиться в текущем сегменте кода или в некотором другом сегменте. В первом случае переход называется внутрисегментным, или близким, во втором — межсегментным, или дальним.

Внутрисегментный переход предполагает, что изменяется только содержимое регистра EIP/IP.

Команда косвенного межсегментного перехода в качестве операнда включает в себя адрес области памяти, в которой содержатся смещение и сегментная часть целевого адреса перехода.

Условные переходы

В системе команд процессора IA-32 есть большая группа команд, призванных самостоятельно принимать решение о том, какая команда должна выполняться следующей. Решение принимается в зависимости от определенных условий, определяемых конкретной командой перехода. Процессор поддерживает 18 команд условного перехода, позволяющих проверить:

отношение между операндами) со знаком (больше или меньше);

отношение между операндами без знака (выше или ниже);

состояниями арифметических флагов ZF, SF, CF, OF, PF (но не AF).

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

jcc метка_перехода

Для того чтобы принять решение о том, куда будет передано управление командой условного перехода, предварительно должно быть сформировано условие, на основании которого должно приниматься решение. Источниками такого условия могут быть:

любая команда, изменяющая состояние арифметических флагов;

команда СМР, сравнивающая значения двух операндов;

состояние регистра ЕСХ/СХ.

Команда сравнения СМР (СоМРаrе) имеет следующий принцип работы. Команда СМР так же, как и команда SUB, выполняет вычитание операндов и по результатам сравнения устанавливает флаги. При этом записи результата вычитания на место первого операнда не происходит.

Синтаксис команды СМР:

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

В листинге 1 приведен пример программы, производящей в строке символов длиной п байт замену строчных букв английского алфавита прописными. Строчные и прописные буквы в таблице ASCII упорядочены по алфавиту. Строчным буквам соответствует диапазон кодов 61h-7ah, прописным — 41h-5ah. Для того чтобы понять идею, лежащую в основе алгоритма преобразования, достаточно сравнить представления соответствующих прописных и строчных букв в двоичном виде:

а - 0110 0001..z – 0111 1010

А - 0100 0001...Z – 0101 1010.

Как видно из приведенного двоичного представления, для выполнения преобразования между строчными и прописными буквами достаточно всего лишь инвертировать 5-й бит.

Листинг 1. Смена регистра символов

<1>

;

model small

.stack 100h

.data

n equ 10

stroka db 'acvfgrndup'

.code

start:

mov ax,@data

mov ds,ax

xor ax,ax

mov cx,n

lea bx,stroka ;адрес stroka в bx

m1: mov al,[bx] ;очередной символ из stroka в al

cmp al,61h ;проверить, что код символа не меньше 61h

jb next ;если меньше, то не обрабатывать и на следующий символ

cmp al,7ah ;проверить, что код символа не больше 7аh

ja next ;если больше, то не обрабатывать и на следующий символ

and al,11011111b ;инвертировать 5-й бит

mov [bx],al ;символ на место в stroka

next:

inc bx ;адресовать следующий символ

dec cx ;уменьшить значение счетчика в cx

jnz m1 ;если cx не 0, то переход на m1

exit:

mov ax,4c00h

int 21h ;возврат управления операционной системе

end start

<2>

<3>

<4>

<5>

<6>

<7>

<8>

<9>

<10>

<11>

<12>

<13>

<14>

<15>

<16>

<16>

<18>

<19>

<20>

<21>

<22>

<23>

<24>

<25>

<26>

<27>

<28>

<29>

<30>

В строке 25 команда DEC уменьшает значение регистра СХ на 1. Когда это значение станет равным 0, процессор по результату операции декремента установит флаг ZF. Команда в строке 26 анализирует состояние этого флага и, пока он не равен 1, передает управление на метку ml. Причем на место этой команды можно было бы поставить команду JNE. Но для анализа регистра СХ в системе команд процессора есть специальная команда, которая рассматривается в дальнейшем.

Команды условного перехода и регистр ЕСХ/СХ

Регистр ЕСХ/СХ в архитектуре процессора имеет определенное функциональное назначение — он выполняет функции счетчика в командах управления циклами и при работе с цепочками символов. Возможно, что функционально команды условного перехода, связанные с регистром ЕСХ/СХ, правильнее было бы отнести к этой группе команд.

Синтаксис команд JCXZ (Jump if ex is Zero — переход, если СХ ноль) и JECXZ (Gump Equal ecx Zero — переход, если ЕСХ ноль) таков:

jcxz/jecxz метка_перехода

Эти команды используются при организации цикла и при работе с цепочками символов. В отличие от других команд условной передачи управления, команды JCXZ/JECXZ могут адресовать только короткие переходы — на -128 байт или на +127 байт от следующей за ней команды.

Установка байта по условию

При рассмотрении команд условного перехода логично упомянуть еще об одной команде — SETcc. Данная команда впервые появилась в процессоре i386. Ее формат: SETcc операнд1.

Команда устанавливает байт операнд1 после проверки модификатора ее, задающего условие, аналогично тому, как это делается в командах условного перехода. Фактически, модификатор «сс» обозначает флаг, который нужно проверить. В качестве операнда используется либо один из 8-разрядных регистров (AL, АН, BL, BH, CL, CH, DL, DH), либо адрес ячейки памяти размером в байт. Алгоритм работы команды заключается в том, что значение операнда устанавливается по результатам проверки условия, заданного модификатором «сс»:

операнд1 = 0 — если условие ложно;

операнд1 = 1 — если условие истинно.

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

Цикл представляет собой важную алгоритмическую структуру, без которой не обходится ни одна программа. Организовать циклическое выполнение некоторого фрагмента программы можно, к примеру, используя команды условной передачи управления или команду безусловного перехода JMP.

Например, подсчет количества нулевых байтов в области mas (листинг 2).

Листинг 2. Подсчет числа нулевых элементов

<1>

;

model small

.stack 100h

.data

len equ 10 ;количество элементов в mas

mas db 1,0,9,8,0,7,8,0,2,0

.code

start:

mov ax,@data

mov ds,ax

mov cx,len ;длину поля mas в cx

xor ax,ax

xor si,si

cycl:

jcxz exit ;проверка cx на 0, если 0, то на выход

cmp mas[si],0 ;сравнить очередной элемент mas с 0

jne m1 ;если не равно, то на m1

inc al ;в al счетчик нулевых элементов

m1:

inc si ;перейти к следующему элементу

dec cx ;уменьшить cx на 1;

jmp cycl

exit:

mov ax,4c00h

int 21h ;возврат управления операционной системе

end start

<2>

<3>

<4>

<5>

<6>

<7>

<8>

<9>

<10>

<11>

<12>

<13>

<14>

<15>

<16>

<16>

<18>

<19>

<20>

<21>

<22>

<23>

<24>

<25>

<26>

Цикл в листинге 2 организован тремя командами, JCXZ, DEC и JMP (строки 15, 21 и 22).

Команда JCXZ выполняет здесь две функции: предотвращает выполнение «пустого» цикла (когда счетчик цикла в СХ равен нулю) и отслеживает окончание цикла после обработки всех элементов поля mas.

Команда DEC после каждой итерации цикла уменьшает значение счетчика в регистре СХ на 1. При такой организации цикла все операции по его организации выполняются «вручную». Но, учитывая важность такого алгоритмического элемента, как цикл, разработчики процессора ввели в систему команд группу из трех команд, облегчающую программирование циклов. Эти команды также используют регистр ЕСХ/СХ как счетчик цикла.

К числу таких команд относится команда LOOP, которая позволяет организовать циклы (loops), подобные циклам for в языках высокого уровня с автоматическим уменьшением счетчика цикла. Синтаксис команды:

loop метка_перехода

Команда реализует следующие действия:

  1. Декремент регистра ЕСХ/СХ.

  2. Сравнение регистра ЕСХ/СХ с нулем:

если (ЕСХ/СХ) > 0, то управление передается на метку перехода;

если (ЕСХ/СХ) = 0, то управление передается на следующую после LOOP команду.

Команды LOOPE и LOOPZ (Loop still сх <> 0 or Zero flag = 0 — повторить цикл пока СХ <> 0 или ZF = 0) — абсолютные синонимы.

Синтаксис команд:

loope/loopz метка_перехода

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

  1. Декремент регистра ЕСХ/СХ.

  2. Сравнение регистра ЕСХ/СХ с нулем и анализ состояния флага нуля ZF:

если (ЕСХ/СХ) > 0 и ZF = 1, управление передается на метку перехода;

если (ЕСХ/СХ) = 0 и ZF = 0, управление предается на слудующую после LOOP команду.

Команды LOOPE/LOOPZ и LOOPNE/LOOPNZ по принципу своей работы являются взаимообратными. Они расширяют действие команды LOOP тем, что дополнительно анализируют флаг ZF. Это дает возможность организовать досрочный выход из цикла, используя этот флаг в качестве индикатора. Типичное применение этих команд связано с операцией поиска определенного значения в последовательности или со сравнением двух чисел.

Недостаток команд организации цикла LOOP, LOOPE/LOOPZ и LOOPNE/LOOPNZ заключается в том, что они реализуют только короткие переходы (от -128 до +127 байт). Для работы с длинными циклами используются команды условного перехода и команда JMP (листинг 2).

Рассмотрим несколько примеров организации циклов с помощью команд LOOP, LOOPE/LOOPZ и LOOPNE/LOOPNZ.

Соседние файлы в папке УМК_Орг_ЭВМ