- •Московский государственный открытый университет
- •Лекции по
- •Чебоксары 2006 Лекция 1. Архитектура центрального процессора пэвм
- •Лекции 2,3. Определение данных. Команды пересылки данных
- •Лекция 4. Основы языка ассемблер
- •Лекция 5. Арифметические команды.
- •Лекция 6. Логические операции
- •Лекция 7. Сегменты и передача управления.
- •Лекция 8 Регистр флагов Flags и условные переходы
- •Лекция 9 Организация циклов.
- •Лекции 10,11 программы и подпрограммы. Связь по управлению и по данным
- •Лекция 12 Прерывания
- •Контроллер прерываний и микропроцессоры 80х86.
- •Лекция 13 сопроцессор и его программирование
- •Лекция 14
Лекция 9 Организация циклов.
LOOP Переход по счетчику
Признаки не меняются .
LOOP short-label .
логика: CX = CX - 1
if (CX <> 0)
JMP short-label .
Команда LOOP уменьшает CX на 1, затем передает управление по метке short-label, если CX не равно 0. Операнд short-label должен находиться в пределах от -128 до +127 байтов от следующей команды.
-------------------------------------------------------------
Операнды Такты Обращения Байты Пример
short-label 17/5 - 2 LOOP AGAIN
2.6.33 LOOPE Переход пока равно
Признаки не меняются.
Команда: LOOPE short-label .
Логика: CX = CX - 1
if (CX <> 0) and (ZF = 1)
JMP short-label .
Команда LOOPE используется после команд CMP или SUB. Она уменьшает CX на 1, затем передает управление по метке short-label, если CX не равно нулю и если первый операнд команд CMP или SUB был равен второму операнду. Операнд short-label должен находиться в пределах от -128 до +127 байтов от следующей команды.
-------------------------------------------------------------
Операнды Такты Обращения Байты Пример
short-label 18 или 6 - 2 LOOPE AGAIN
Примечание: Команда LOOPZ, переход пока ноль, - это та же команда, что и LOOPE.
2.6.34 LOOPNE Переход пока не равно
Признаки не меняются .
Команда: LOOPNE short-label .
Логика: CX = CX - 1
if (CX <> 0) and (ZF = 0)
JMP short-label .
Команда LOOPNE используется после команд CMP или SUB. Она уменьшает CX на 1, затем передает управление по метке short-label, если CX не равно нулю и если первый операнд команд CMP или SUB не равен второму операнду. Операнд short-label должен находиться в пределах от -128 до +127 байтов от следующей команды.
-------------------------------------------------------------
Операнды Такты Обращения Байты Пример
short-label 18 или 6 - 2 LOOPNE AGAIN
Примечания:
Команда LOOPNZ, переход пока не ноль, - это та же команда, что и LOOPNE.
2.6.35 LOOPNZ Переход пока не ноль
LOOPZ - синоним LOOPE. См. описание LOOPE.
Лекции 10,11 программы и подпрограммы. Связь по управлению и по данным
В целях структуризации программ, облегчения их разработки, отладки и понимания большие программы принято разбивать на отдельные модули, логически связанные друг с другом и достаточно автономные. Идея структурного программирования заключается в том, что структура программы должна отражать структуру решаемой задачи, чтобы алгоритм решения был ясно виден из исходного текста. С этой целью было введено понятие подпрограммы – набора операторов, выполняющих нужное действие и не зависящих от других частей исходного кода. Обычно критическим порогом размера подпрограммы, необходимого для быстрого понимания цели подпрограммы, считается 50 операторов. Возможность применения подпрограмм относит язык программирования к классу процедурных языков.
Наличие подпрограмм позволяет вести проектирование приложения сверху вниз, решая сначала глобальные задачи, а потом детализируя каждую из них. Подпрограммы бывают двух типов – процедуры и функции. Процедура выполняет некоторую группу операторов, а функция вдобавок вычисляет некоторое значение и возвращает его в главную программу. В неё же возвращается и поток управления командами программы, причем подпрограмма должна уметь вернуть управление независимо от того, откуда она была вызвана. Вызов подпрограмм может быть вложенным. Чтобы работа программы имела смысл, ей надо получить данные из внешней (вызывающей) программы. Данные передаются в виде параметров или аргументов в виде списка, метод доступа к которому стандартизован и имеет аппаратную поддержку. В микропроцессорах INTEL такой поддержкой является аппаратный стек и команды работы с ним. Подпрограмма может иметь свои собственные локальные переменные, существующие только в интервале времени от входа в подпрограмму до выхода из нее, а также разделять с другими подпрограммами и главной программой доступ к глобальным переменным.
Процесс взаимодействия вызывающей программы и вызываемой подпрограммы состоит из ряда последовательных этапов по следующему протоколу:
Вызывающая программа:
-
Подготовить список параметров согласно соглашениям о связях;
-
Подготовить для подпрограммы адрес возврата;
-
Передать управление в подпрограмму.
Вызываемая подпрограмма:
-
Сохранить состояние среды (контекст) вызывающей программы (в некоторых реализациях это действие выполняет операционная система);
-
Выделить память для локальных переменных;
-
Получить доступ к параметрам;
-
Выполнить алгоритм, заложенный в подпрограмму; при необходимости воспользоваться списком параметров, правильно извлекая и изменяя из значения в соответствии с соглашениями о связях;
-
Освободить память локальных переменных и восстановить контекст вызывавшей программы;
-
Возвратить управление в вызывавшую программу;
Вызывающая программа:
-
Воспользоваться результатами работы подпрограммы.
Параметры, передаваемые в подпрограмму в момент её вызова, называются фактическими. Они замещают формальные параметры, указываемые в заголовке подпрограммы. Параметры могут передаваться по адресу (по имени) или по значению. Последние не могут изменить свои значения в вызывающей программе. По адресу передаются изменяемые параметры, а также массивы и структуры. Подпрограммы бывают реентерабельные (или повторновходовые) – это те, которые допускают вызов какой-либо собственной функции изнутри себя самой. Для их написания необходимо соблюдать некоторые правила, например, не использовать локальные переменные. Рекурсивные подпрограммы позволяют делать вызов себя из себя самой (классический пример – рекурсивное определение факториала).
Реализация описанных понятий происходит по-разному в зависимости от архитектуры аппаратных средств и операционной системы. Для микропроцессоров INTEL традиционным является использование аппаратного стека. Структура информации, соответствующая описанному выше протоколу, дана на следующем рисунке. Она образует «фрейм», или «кадр» стека. Следует помнить, что логический рост стека на данных микропроцессорах происходит «сверху вниз», от больших адресов к меньшим.
Рис. 1. Структура фрейма вызова подпрограммы
CALL Вызов подпрограммы
Признаки не меняются.
Команда: CALL procedure_name .
Логика: if FAR CALL (внешний сегмент)
PUSH CS
CS = dest_seg
PUSH IP
IP = dest_offset .
CALL передает управление подпрограмме, которая может находиться как внутри текущего сегмента (NEAR-proc), так и вне его (FAR-proc). Этим двум типам CALL соответствуют две различные машинные команды, и команда RET возврата из подпрограммы должна соответствовать типу команды CALL (потенциальная возможность несоответствия возникает, когда подпрограмма и команда CALL ассемблируются раздельно).
Примечания:
Если подпрограмма находится в другом сегменте, то процессор засылает в стек сначала текущее значение CS, затем текущее значение IP (IP указывает на команду, следующую за командой CALL), а затем передает управление в подпрограмму. Если же подпрограмма находится в том же сегменте, то процессор засылает в стек сначала текущее значение IP (которое опять же указывает на команду, следующую за командой CALL), а затем передает управление в подпрограмму. CALL также может считать адрес подпрограммы из регистра или из памяти. Эта форма команды CALL называется косвенным вызовом.
2.5.3 RET Возврат из подпрограммы
Признаки не меняются .
Команда: RET optional-pop-value .
Логика: POP IP
if FAR RETURN (внешний сегмент)
POP CS
SP = SP + optional-pop-value (если оно имеется) .
Команда RET передает управление из вызванной подпрограммы команде, следовавшей непосредственно за CALL, и делает это следующим образом :
- пересылает слово из верхушки стека в IP;
- если возврат осуществляется во внешний сегмент, то пересылает слово из новой верхушки стека в CS;
- увеличивает SP на значение операнда optional-pop-value, если оно задано.
Ассемблер сгенерирует возврат во внутренний сегмент, если подпрограмма, содержащая RET, будет обозначена программистом как NEAR, и возврат во внешний сегмент, - если как FAR. Операнд optional-pop-value определяет значение, которое надо прибавить к SP, что имеет смысл "освобождения" стека от "лишних" байтов (например, от входных параметров, когда они передаются подпрограмме через стек).