4 какие действия выполняют команды передачи управления
Перейти к содержимому

4 какие действия выполняют команды передачи управления

  • автор:

Лекция 9.Команды передачи управления. Процедуры

Мы познакомились с некоторыми командами, из которых формируются линейные участки программы. Каждая из них в общем случае выполняет некоторые действия по преобразованию или пересылке данных, после чего микропроцессор передает управление следующей команде. Но очень мало программ работает таким последовательным образом. Обычно в программе есть точки, в которых нужно принять решение о том, какая команда будет выполняться следующей. Это решение может быть:

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

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

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

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

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

2) eip/ip – регистр указателя команды, в котором находится значение, представляющее собой смещение в памяти следующей команды, подлежащей выполнению, относительно начала текущего сегмента кода.

Какой конкретно регистр будет использоваться, зависит от установленного режима адресации use16 или use32. Если указано use 16, то используется ip, если use32, то используется eip.

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

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

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

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

2) команда вызова процедуры и возврата из процедуры;

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

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

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

2) команды перехода по состоянию определенного флага;

3) команды перехода по содержимому регистра есх/сх.

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

1) команда организации цикла со счетчиком есх/сх;

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

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

Предыдущее обсуждение выявило некоторые детали механизма перехода. Команды перехода модифицируют регистр указателя команды eip/ip и, возможно, сегментный регистр кода cs. Что именно должно подвергнуться модификации, зависит:

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

2) от указания перед адресом перехода (в команде перехода) модификатора; при этом сам адрес перехода может находиться либо непосредственно в команде (прямой переход), либо в регистре или ячейке памяти (косвенный переход).

Модификатор может принимать следующие значения:

1) near ptr – прямой переход на метку внутри текущего сегмента кода. Модифицируется только регистр eip/ip (в зависимости от заданного типа сегмента кода use16 или use32) на основе указанного в команде адреса (метки) или выражения, использующего символ извлечения значения – $;

2) far ptr – прямой переход на метку в другом сегменте кода. Адрес перехода задается в виде непосредственного операнда или адреса (метки) и состоит из 16-битного селектора и 16/32-битного смещения, которые загружаются, соответственно, в регистры cs и ip/eip;

3) word ptr – косвенный переход на метку внутри текущего сегмента кода. Модифицируется (значением смещения из памяти по указанному в команде адресу, или из регистра) только eip/ip. Размер смещения 16 или 32 бит;

4) dword ptr – косвенный переход на метку в другом сегменте кода. Модифицируются (значением из памяти – и только из памяти, из регистра нельзя) оба регистра – cs и eip/ip. Первое слово/двойное слово этого адреса представляет смещение и загружается в ip/eip; второе/третье слово загружается в cs. Команда безусловного перехода jmp

Синтаксис команды безусловного перехода – jmp [модификатор] адрес_перехода – безусловный переход без сохранения информации о точке возврата.

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

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

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

Можно выделить три варианта внутрисегментного использования команды jmp:

1) прямой короткий;

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

1) механизм процедур;

3) механизм прерываний.

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

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

Для описания последовательности команд в виде процедуры в языке ассемблера используются две директивы: PROC и ENDP.

Синтаксис описания процедуры таков (рис. 36).

Рис. 36. Синтаксис описания процедуры в программе

Из рисунка 36 видно, что в заголовке процедуры (директиве PROC) обязательным является только задание имени процедуры. Среди большого количества операндов директивы PROC следует особо выделить [расстояние]. Этот атрибут может принимать значения near или far и характеризует возможность обращения к процедуре из другого сегмента кода. По умолчанию атрибут [расстояние] принимает значение near.

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

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

Микропроцессор имеет 18 команд условного перехода. Эти команды позволяют проверить:

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

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

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

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

Как видно, мнемокод всех команд начинается с «j» – от слова jump (прыжок), ее – определяет конкретное условие, анализируемое командой.

Что касается операнда метка_перехода, то эта метка может находиться только в пределах текущего сегмента кода, межсегментная передача управления в условных переходах не допускается. В связи с этим отпадает вопрос о модификаторе, который присутствовал в синтаксисе команд безусловного перехода. В ранних моделях микропроцессора (i8086, i80186 и i80286) команды условного перехода могли осуществлять только короткие переходы – на расстояние от —128 до +127 байт от команды, следующей за командой условного перехода. Начиная с модели микропроцессора 80386, это ограничение снято, но, как видите, только в пределах текущего сегмента кода.

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

Источниками такого условия могут быть:

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

2) команда сравнения стр, сравнивающая значения двух операндов;

3) состояние регистра есх/сх.

Команда сравнения cmp

Команда сравнения стр имеет интересный принцип работы. Он абсолютно такой же, как и у команды вычитания – sub операнде, операнд_2.

Команда стр так же, как и команда sub, выполняет вычитание операндов и устанавливает флаги. Единственное, чего она не делает – это запись результата вычитания на место первого операнда.

Синтаксис команды стр – стр операнд_1, операнд_2 (compare) – сравнивает два операнда и по результатам сравнения устанавливает флаги.

Флаги, устанавливаемые командой стр, можно анализировать специальными командами условного перехода. Прежде чем мы их рассмотрим, уделим немного внимания мнемонике этих команд условного перехода (табл. 16). Понимание обозначений при формировании названия команд условного перехода (элемент в названии команды jcc, обозначенный нами ее) облегчит их запоминание и дальнейшее практическое использование.

Таблица 16. Значение аббревиатур в названии команды jcc

Таблица 17. Перечень команд условного перехода для команды стр операнд_1, операнд_2

He удивляйтесь тому обстоятельству, что одинаковым значениям флагов соответствует несколько разных мнемокодов команд условного перехода (они отделены друг от друга косой чертой в табл. 17). Разница в названии обусловлена желанием разработчиков микропроцессора облегчить использование команд условного перехода в сочетании с определенными группами команд. Поэтому разные названия отражают скорее различную функциональную направленность. Тем не менее то, что эти команды реагируют на одни и те же флаги, делает их абсолютно эквивалентными и равноправными в программе. Поэтому в таблице 17 они сгруппированы не по названиям, а по значениям флагов (условиям), на которые они реагируют.

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

Мнемоническое обозначение некоторых команд условного перехода отражает название флага, с которым они работают, и имеет следующую структуру: первым идет символ «j» (Jump, переход), вторым – либо обозначение флага, либо символ отрицания «n», после которого стоит название флага. Такая структура команды отражает ее назначение. Если символа «n» нет, то проверяется состояние флага, если он равен 1, производится переход на метку перехода. Если символ «n» присутствует, то проверяется состояние флага на равенство 0, и в случае успеха производится переход на метку перехода.

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

Таблица 18. Команды условного перехода и флаги

Если внимательно посмотреть на таблицы 17 и 18, видно, что многие команды условного перехода в них являются эквивалентными, так как в основе и тех, и других лежит анализ одинаковых флагов.

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

Архитектура микропроцессора предполагает специфическое использование многих регистров. К примеру, регистр EAX/AX/AL используется как аккумулятор, а регистры ВР, SP – для работы со стеком. Регистр ЕСХ/СХ тоже имеет определенное функциональное назначение: он выполняет роль счетчика в командах управления циклами и при работе с цепочками символов. Возможно, что функционально команду условного перехода, связанную с регистром есх/сх, правильнее было бы отнести к этой группе команд.

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

1) jcxz метка_перехода (Jump if ex is Zero) – переход, если сх нуль;

2) jecxz метка_перехода (Jump Equal есх Zero) – переход, если есх нуль.

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

Нужно отметить ограничение, свойственное команде jcxz/jecxz. В отличие от других команд условной передачи управления команда jcxz/jecxz может адресовать только короткие переходы – на —128 байт или на +127 байт от следующей за ней команды.

12.Команды передачи управления: условные и безусловные. Вызов процедур и прерываний, возврат управления после процедуры или прерывания.

Команды JMP, CALL, RET, INT и IRET передают выполнение адресату в программном сегменте. Адресат может находиться как в том же программном сегменте (близкая передача), так и в другом программном сегменте (дальняя передача).

Команда перехода

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

Команды вызова процедур

CALL (Вызов процедуры) передает управление и сохраняет адрес команды, следующей за командой CALL, для дальнейшего использования командой RET (Возврат). CALL сохраняет текущее содержимое регистра EIP в стеке. Команда RET в вызванной процедуре использует этот адрес в стеке для передачи управления назад в вызывающую программу. Команды CALL и JMP имеют абсолютный и относительный форматы. Косвенная команда CALL указывает абсолютный адрес одним из следующих способов.

Команды возврата и возврата-из-прерывания

RET (Возврат из процедуры) завершает выполнение процедуры и передает управление команде, следующей за командой CALL, которая вызвала данную процедуру.

Команда RET восстанавливает содержимое регистра EIP, которое было сохранено в стеке при вызове процедуры. Команда RET имеет необязательный операнд непосредственного значения. Когда операнд имеется, эта константа прибавляется к содержимому регистра ESP, что имеет эффект удаления всех параметров, сохраненных в стеке перед вызовом процедуры.

IRET (Возврат из прерывания) возвращает управление прерванной процедуре. Команда IRET отличается от команды RET тем, что она восстанавливает содержимое регистра EFLAGS из стека. Содержимое регистра EFLAGS запоминается в стеке при возникновении прерывания.

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

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

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

В Таблице 3-3 приведена мнемоника команд перехода. Команды, приведенные парами, являются альтернативными именами одной и той же команды. Язык ассемблера поддерживает эти имена для большей ясности листингов программ. Разрешена форма команды условного перехода, которая использует смещение, суммируемое с содержимым регистра EIP, если указанное условие верно. Смещение может быть байтом или двойным словом. Смещение имеет знак; оно может быть использовано для перехода вперед и назад.

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

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

LOOP приводит к выполнению части программы, которое повторяется до тех пор, пока счетчик не станет равным нулю. Когда достигается значение нуля, выполнение передается команде, следующей непосредственно за командой LOOP. Если значение регистра ECX равняется нулю перед первым выполнением цикла, счетчик цикла умеьшается на 1, регистру присваивается значение 0FFFFFFFFH и цикл выполняется 2**32 раза.

LOOPE (Цикл до тех пор, пока равенство) и LOOPZ (Цикл до тех пор, пока ноль) являются синонимами одной и той же команды. Эти командыявляются командами условного перехода, которые уменьшают содержимое регистра ECX перед проверкой условия завершения цикла. Если значение регистра ECX не равно нулю и установлен флаг ZF, программа передает управление по адресу, указанному в качестве операнда назначения в команде. Когда достигнуто значение нуля или флаг ZF очищен, выполнение передается команде, следующей непосредственно за командой LOOPE/ LOOPZ.

LOOPNE (Цикл до тех пор, пока неравенство) и LOOPNZ (Цикл до тех пор, пока не ноль) являются синонимами одной и той же команды. Эти команды являются командами условного перехода, которые уменьшают содержимое регистра ECX перед проверкой условия завершения цикла. Если значение регистра ECX не равно нулю и очищен флаг ZF, программа передает управление по адресу, указанному в качестве операнда назначения в команде. Когда достигнуто значение нуля или флаг ZF установлен, выполнение передается команде, следующей непосредственно за командой LOOPNE /LOOPNZ.

Выполнение цикла или повтор ноль раз

JECXZ (Переход, если ECX равен нулю) переходит по адресу, указанному в команде в качестве операнда назначения, если в регистре ECX содержится значение ноль. Команда JECXZ используется совместно с командой LOOP и с командами сканирования строки и сравнения. Так как эти команды уменьшают значение регистра ECX перед проверкой на ноль, цикл будет выполняться 2**32 раза, если обращение к циклу произошло, когда в регистре ECX содержалось значение ноль. Команда JECXZ используется для создания циклов, которые пропускаются без выполнения, если начальное значение равно нулю. Команда JECXZ в начале цикла может быть использована для перехода за пределы цикла, если значение счетчика цикла равняется нулю. Когда команда используется вместе с повторяющимся командами сканирования строки и сравнения, JECXZ может определить условие окончания цикла до достижения счетчиком значения нуля или до выполнения условий сканирования или сравнения.

Программные прерывания

Команды INT, INTO и BOUND позволяют программисту осуществлять передачу управления программе обработки прерываний или исключениям.

INTn (Программное прерывание) вызывает программу обработки, указанную вектором прерываний, заданным в команде. Команда INT может задавать любые типы прерываний. Эта команда используется для поддержки множества типов программных прерываний или для проверки работы сервисных программ обработки прерываний. Сервисные программы обработки прерываний завершаются командой IRET, которая передает управление к команде, следующей за командой INT.

INTO (Прерывание по переполнению) вызывает программу обработки исключений по переполнению, если установлен флаг OF. Если данный флаг очищен, выполнение продолжается без вызова программы обработки. Флаг OF устанавливается арифметическими и логическими командами и командами работы со строками. Команда INTO поддерживает использование программных прерываний для обработки ошибочных ситуаций, таких, как арифметическое переполнение.

BOUND (Обнаружить выход значения за допустимые границы) сравнивает значение со знаком, хранящееся в регистре общего назначения, с верхним и нижним пределами. Программа обработки исключений по контролю выхода за допустимые границы вызывается, если значение, содержащееся в регистре, меньше чем нижняя граница, или больше чем верхняя граница. Эта команда поддерживает использование программных прерываний для контроля выхода за допустимые границы, таких как проверка индекса массива, чтобы убедиться в том, что он попадает в диапазон границ, заданный для массива. Команда BOUND имеет два операнда. Первый операнд указывает регистр общего назначения, который необходимо проверить. Второй операнд указывает базовый адрес двух слов или двух двойных слов, расположенных по соседству в памяти. Нижней границей является слово или двойное слово с младшим адресом, верхняя граница имеет старший адрес. Команда BOUND предполагает, что верхнее граничное значение и нижнее граничное значение расположены в смежных ячейках памяти. Верхняя и нижняя граница не могут быть операндами-регистрами; если же они таковыми являются, возникает исключение по неверному коду операции. Верхняя и нижняя границы массива могут располагаться в памяти даже до самого массива. Это позволяет задавать границы массива как постоянное смещение относительно начала массива. Так как адрес массива уже должен находиться в регистре, такая практика позволяет избежать дополнительных циклов шины для получения эффективной адресации границ массива.

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

6.1Классификация команд передачи управления По принципу действия команды микропроцессора можно разделить на три группы: 1. Команды безусловной передачи управления: команда безусловного перехода; вызов процедуры и возврата из процедуры; вызов программных прерываний и возврат из программных прерываний. 2. Команды условной передачи управления: команды перехода по результату команды сравнения; команды перехода по состоянию определенного флага; команды перехода по содержимому регистра есх/СХ. 3. Команды управления циклом: команда организации цикла со счетчиком есх/сх; команда организации цикла со счетчиком есх/сх с возможностью досрочного выхода из цикла; по дополнительному условию. Место, куда необходимо передать управление, делается с помощью меток. Метка символическое имя, обозначающее определенную ячейку памяти, предназначенное для использования в качестве операнда в командах передачи управления. Любой метке можно присвоить три атрибута:

  • имя сегмента кода, где метка описана;
  • смещение — расстояние в байтах от начала сегмента кода, в котором описана метка;
  • тип метки, или атрибут расстояния. Последний атрибут может принимать два значения:
    • Near — переход на метку возможен только в пределах сегмента кода, где эта метка описана;
    • Far — переход па эту метку возможен в результате межсегментной передачи управления.

Метку можно определить двумя способами: Символическое_имя : команда_ассемблера Символическое_имя label тип_метки Введем важное понятие ассемблера — счетчик адреса команд. Транслятор ассемблера обрабатывает исходную программу последовательно — команду за командой. При этом он ведет счетчик адреса команд, который для первой исполняемой команды равен 0, а далее, по ходу обработки очередной команды транслятором, он увеличивается па длину этой команды. Счетчик адреса команд — смещение конкретной команды относительно начала сегмента кода. Каждая команда имеет адрес, равный значению счетчика адреса команд. Транслятор ассемблера обеспечивает нам две возможности работы с этим счетчиком:

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

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

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

Синтаксис команды: Jmp [модификатор] адрес_перехода — безусловный переход без сохранения информации о точке возврата. Адрес_перехода представляет собой адрес в виде метки либо адрес области памяти, в которой находится указатель перехода. Модификатор может принимать следующие значения: Near ptr — прямой переход на метку внутри текущего сегмента кода. Far ptr — прямой переход на метку в другом сегменте кода. Word ptr — косвенный переход на метку внутри текущего сегмента кода. Dword ptr — косвенный переход на метку в другом сегменте кода. Команда безусловного перехода может использоваться в 5 разновидностях. Переход может быть: прямым коротким (в пределах -128. +127 байтов); прямым ближним (в пределах текущего сегмента команд); прямым дальним (в другой сегмент команд); косвенным ближним (в пределах текущего сегмента команд через ячейку с адресом перехода); косвенным дальним (в другой сегмент команд через ячейку с адресом перехода). Рассмотрим структуры программы с переходами разного вида:

        1. Прямой короткий переход.

seg segment ‘code’ .. jmp short сont .. cont: .. seg ends

        1. Прямой ближний (внутрисегментный) переход.

seg segment ‘code’ .. jmp cont .. cont: .. seg ends

        1. Прямой дальний (межсегментный) переход.

segl segment ‘code’ .. jmp far ptr cont .. segl ends seg2 segment ‘code’ .. cont: .. seg2 ends

        1. Косвенный ближний (внутрисегментный) переход,

segl segment ‘code’ .. jmp DS: contadr .. cont: .. segl ends dat segment .. contadr dw conl .. dat ends 5. Косвенный дальний (межсегментный) переход. segl segment ‘code’ .. jmp DS: contadr .. segl ends seg2 segment ‘code’ .. cont: .. seg2 ends dat segment .. contadr dd cont .. dat ends 6.3 Понятие процедуры в языке ассемблера Процедура (подпрограмма) — это основная функциональная единица декомпозиции (разделения на несколько частей) некоторой задачи. Процедуру можно определить как правильным образом оформленную совокупность команд, которая при необходимости может быть вызвана в любом месте программы. Синтаксис: Имя_процедурыPROC [[модификатор языка] язык] [расстояние] заголо- [ARG список_аргументов] вок [RETURN список_элементов] проц. команды, тело директивы ассемблера проц. … конец [имя_процедуры] ENDP проц. Процедура может располагаться в программе: — в начале программы (до первой исполняемой команды);

  • в конце (после команды, возвращающей управление операционной системе);
  • промежуточный вариант — тело процедуры располагается внутри другой процедуры или основной программы;
  • в другом модуле.

Call [модификатор] имя_процедуры — вызов процедуры. Ret [число] — возвратить управление вызывающей программе. Команда считывает адрес возврата из стека и загружает его в регистры cs и ip/eip, тем самым возвращая управление на команду, следующую в программе за командой call, [число] — количество элементов, удаляемых из стека при возврате из процедуры. Команда вызова подпрограммы может использоваться в 4 разновидностях. Вызов может быть:

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

— косвенным дальним (в другой сегмент команд через ячейку с адресом перехода). Рассмотрим структуру программных комплексов: 1. Прямой ближний вызов. seg segment ‘code’ mymain proc … call sub … mumain endp sub proc near … ret sub endp seg ends 2. Прямой дальний вызов. segl segment ‘code’ mymain proc … call far ptr sub … mumain endp segl ends seg2 segment ‘code’ sub proc far … ret sub endp seg2 ends

  1. Косвенный ближний вызов.

seg segment ‘code’ mymain proc … call word ptr subadr mumain endp sub proc near … ret sub endp dat segment … subadr dw sub … dat ends

  1. Косвенный дальний вызов.

Segl segment ‘code’ mymain proc call dword ptr subadr … mumain endp segl ends seg2 segment ‘code’ sub proc far … ret sub endp seg2 ends dat segment … subadr dd sub … dat ends

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

Эти команды позволяют проверить:

  • отношение между операндами со знаком (больше — меньше);
  • отношение между операндами без знака (выше — ниже);
  • состояниями арифметических флагов zf, sf, cf, of, pf.

Синтаксис: Jcc метка_перехода ее — определяет конкретное условие, анализируемое командой. Источниками условия могут быть:

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

Синтаксис команды cmp: cmp операнд1, операнд2 — сравнивает два операнда и по результатам сравнения устанавливает флаги. Таблица 9. Перечень команд условного перехода.

Типы операндов Мнемокод Критерий перехода
Любые Je Операнд 1 =операнд2
Любые Jne Операнд 1 <>операнд2
Со знаком Л / Jnge Операнд!
Со знаком Jle / Jng Операнд 1
Со знаком Jg / Me Операнд 1>операнд2
Со знаком Jge / Jnl Операнд 1 =>операнд2
Без знака Jb / Jnae Операнд 1
Без знака Jbe / Jna Операнд 1
Без знака Ja / Jnbe Операнд 1 >операнд2
Без знака Jae / Jnb Операнд 1 =>операнд2

Таблица 10. Команды условного перехода и флаги.

Название флага Номер бита Команда условного перехода Значение флага для осуществления перехода
Флаг перноса cf 1 Jc Cf=l
Флаг четности pf 2 Jp Pf=l
Флаг нуля zf 6 Jz Zf=l
Флаг знака sf 7 Js Sf=l
Флаг переполнения of 11 Jo Of=l
Флаг переноса cf 1 Jnc Cf=0
Флаг четности pf 2 Jnp Pf=0
Флаг нуля zf 6 Jnz Zf=0
Флаг знака sf 7 Jns Sf=0
Флаг переполнения of 11 Jno Of=0
  • декремента регистра есх/сх;
  • сравнения регистра есх/сх с нулем;
  • декремента регистра есх/сх;
  • сравнения регистра есх/сх с нулем;
  • анализа состояния флага нуля zf;
  • декремента регистра есх/сх;
  • сравнения регистра есх/сх с нулем;
  • анализа состояния флага нуля zf;
  1. Написать программу, которая задает вопрос: «Сейчас день? (Да/Нет)». По результату ответа на экран выводится одно из двух сообщений: «Добрый день» или «Добрый вечер».
  2. Написать программу преобразования строчных букв в прописные.
  3. Создать текстовый символьный массив (64 символа, от символа пробела до символа _). Вывести созданную строку на экран.
  4. Просмотреть изображения символов второй половины кодовой таблицы (коды 128 – 255, всего 128 символов). Для этого создать символьный массив, состоящий из кодов этих символов, и вывести их на экран.
  5. Создать программную задержку. Определить значение параметров программы, позволяющие получить задержки 10с.
  6. Во введенной с клавиатуры строки подсчитать количество слов.

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

Адрес следующей выполняемой микропроцессором команды определяется содержимым его регистров CS:IP (EIP в случае 32-х разрядной адресации). Причем, если все команды находятся в одном сегменте кодов, то при переходе к следующей команде изменяется только содержимое указателя команд IP.

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

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

  • • безусловных переходов;
  • • условных переходов;
  • • вызовов;
  • • возвратов;
  • • управления циклами;
  • • прерываний.

При выполнении команд передачи управления флаги не устанавливаются.

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

  • имя сегмента кода, в котором метка описана;
  • смещение — расстояние в байтах от начала этого сегмента кода;
  • тип расстояния, который может быть либо ближним (near) —в случае если помеченная команда находится в текущем сегменте кода, либо дальним (far)- в случае, если помеченная команда находится в другом сегменте кода.

Команда безусловного перехода имеет мнемонику JMP (JuMP — прыжок) и записывается в формате

JMP [модификатор] метка ; перейти на метку.

В зависимости от типа расстояния метки машинные коды команд JMP различаются и имеют пять разновидностей:

  • • прямой короткий переход (short) — адрес перехода лежит в диапазоне-128 . +127.
  • • прямой ближний переход (near) — помеченная команда находится в текущем сегменте кода на расстоянии 128 . 216 адресов от команды JMP;
  • • прямой косвенный ближний переход — адрес перехода задается косвенно с помощью ссылки на регистр или ячейку памяти в которых он находится;
  • • прямой дальний переход (far)- помеченная команда находится в другом сегменте кодов. Изменяется содержимое регистров CS:IP (EIP);
  • • прямой косвенный дальний переход — полный адрес перехода CS:IP (EIP) содержится в ячейках памяти.

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

  • • short — прямой короткий переход;
  • • near ptr — прямой ближний переход;
  • • far ptr — прямой дальний переход;
  • • word ptr — косвенный ближний переход;
  • • dword ptr — косвенный дальний переход.

JMP ш_1 ;прейти на метку m l

JMP near ptr m_l ;прейти на метку m l

MOV BX, offset m_2; загрузить в ВХ адрес ближнего перехода JMP ВХ; перейти на метку адрес которой находится в ВХ.

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

Jcond метка; перейти на метку по условию

Jump — прыжок, Condition — условие, метка — метка перехода, которая может находиться только в текущем сегменте кода. Отсюда следует, что все условные переходы являются короткими или ближними внутрисегментными.

Условия, на основании которых формируется решение о переходе, определяются состоянием флагов микропроцессора. Поэтому при использовании команд условного перехода необходимо следить за тем, чтобы флаги находились в активном состоянии. Активизировать флаги можно выполнением «безобидной» арифметической команды, либо команды сравнения СМР.

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

перейти на метку, если CF = 1 перейти на метку, если CF = О перейти на метку, если PF = 1 перейти на метку, если PF = О перейти на метку, если ZF = 1 перейти на метку, если ZF = О перейти на метку, если SF = 1 перейти на метку, если SF = О перейти на метку, если OF = 1 перейти на метку, если OF = О

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

Команды условных переходов по результатам операции сравнения, приведенные в таблице ниже, позволяют формировать условия перехода на основе анализа нескольких признаков (флагов), сформированных командой сравнить СМР. Такие команды принято делить на команды для анализа беззнаковых чисел ( к ним применяется термины выше (above) — ниже (below)) и для анализа чисел со знаком (термины больше (greater) — меньше (less)). В случае равенства операндов используют термин равно — equal.

СМР АХ, 0 сравнить содержимое АХ с О

JE ш_6 ;если равно, перейти на метку т_6.

СМР ВХ, 1024 сравнить содержимое АХ с числом 1024

JA ш_2 ;если выше, перейти на метку m 2.

ор.1 Ф ор.2 (не равно)

SF = OF и ZF = 0

ор.1 > ор.2 (больше или равно)

CF = 0 и ZF = 0

op. 1 > ор.2 (выше или равно)

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

Достоинства использования подпрограмм-процедур объясняется следующим:

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

Организуются подпрограммы очень просто:

  • • первая команда подпрограммы помечается меткой, которая служит точкой входа в подпрограмму.
  • • завершается подпрограмма командой возврата RET.

Любую подпрограмму можно оформить в виде процедуры. При этом следует использовать следующие правила:

— начинается процедура директивой PROC (Procedure), а завершается директивой ENDP (END Procedure), между которыми располагается тело процедуры:

имя PROC [тип] ;начало процедуры [ARG список аргументов] [RETURN список элементов]

имя ENDP ;конец процедуры.

  • — директивы начала и окончания процедуры обязательно должны иметь имя, которое является именем процедуры. Имя используется как метка первой команды процедуры и означает точку входа в процедуру.
  • — после ключевого слова PROC указывается тип процедуры NEAR (ближняя) или FAR (дальняя) (по умолчанию принимается тип NEAR). Необходимость этого объясняется сегментной организацией памяти и используется для определения того, какой машинный код команды вызова должен сгенерировать микропроцессор при вызове процедуры. Если процедура находится в том же сегменте кода, что и вызывающая команда, она относится к типу NEAR. Если процедура и вызывающая команда находится в разных сегментах, то она относится к типу FAR.
  • — для вызова подпрограммы или процедуры используется команда вызова CALL, которая имеет следующий формат:

CALL метка начала подпрограммы;

CALL имя процедуры;

Если вызываемая подпрограмма-процедура относится к типу NEAR, то генерируется короткая команда внутрисегментного вызова, т. е. машинный код команды CALL содержит внутрисегментное смещение точки входа в процедуру, а адрес возврата (содержимое указателя команд ТР) автоматически помещается в стек.

Если вызываемая процедура относится к типу FAR, то генерируется длинная команда межсегментного вызова, т. е. машинный код команды CALL содержит сегментный адрес и внутрисегментное смещение точки входа в процедуру, а адрес возврата (содержимое регистра CS и указателя команд IP) автоматически помещается в стек.

— тело процедуры должно завершаться безоперандной командой возврата RET. Эта команда восстанавливает в регистрах микропроцессора запомненный в стеке адрес возврата. В процедурах типа

NEAR восстанавливается содержимое указателя команд — регистра IP, а в процедурах типа FAR содержимое двух регистров CS и IP.

Элементарный пример процедуры, которая заносит в регистр СХ среднее значение содержимого регистров АХ и DX приведен ниже:

AVERAGE PROC NEAR

;начать процедуру с именем AVERAGE

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *