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

8

Лекция 14

5.3. Поток управления

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

5.3.1. Последовательный поток управления и переходы

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

Если программа содержит переходы, то счетчик команд уже не является монотонно возрастающей функцией времени. В результате последовательность выполнения команд из самой про­граммы не видна. Чем труднее увидеть последовательность выполнения, тем больше вероятность возникновения ошибок. Такое на­блюдение (Дейкстра) дало толчок революции в программировании, одним из нововведений которой было устранение оператора goto более структурирован­ными формами потока управления, например циклами while. Тем не менее такие программы компилируются в программы машинного уровня, которые могут содержать многочисленные переходы, поскольку реализация операторов if, while и других структур языков высокого уровня требует совершения переходов.

5.3.2. Подпрограммы

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

Особый интерес представляет рекурсивная подпрограмма. Это подпрограмма, которая вызывает сама себя непосредственно либо посредством цепочки других подпрограмм. С помощью рекурсивной подпрограммы легко решается, например, древняя задача о “Ханойской башне”.

5.3.3. Сопрограммы

В обычной последовательности вызовов существует различие между вызы­вающей и вызываемой процедурами. Пусть есть процедура A, кото­рая вызывает процедуру В. После полного выполнения В управление возвращается в А к точке вызова. Если процедура A вызы­вает процедуру В много раз, то процедура В каждый раз начинается с начала, а про­цедура А уже никогда больше с начала не начинается. Когда A вызывает B, она использует команду вызова процедуры (CALL), которая помещает адрес возврата в доступное место, например, в вершину стека. Затем она заносит адрес процедуры B в счетчик команд, чтобы окончательно оформить вызов. Для выхода из процедуры B используется команда (RETURN), которая выталкивает адрес возврата из стека и помещает его в счетчик команд.

Режим работы сопрограмм состоит в том, что A и B более или менее равноправны. Они попеременно вызывают друг друга. Управление каждый раз возвращается к точке последнего вызова. Когда процедура А передает управление процедуре В, оно переходит не к началу В (за исключением первого раза), а к тому месту, на котором произошел предыдущий вызов А.

Сопрограммы обычно используются для того, чтобы производить (псевдо) параллель­ную обработку данных на одном процессоре. Каждая сопрограмма работает псевдопараллельно с другими сопрограммами, как будто у нее есть собственный процес­сор. Такой подход упрощает программирование приложений специального класса. Он так­же полезен для проверки программного обеспечения, которое будет рабо­тать на мультипроцессоре.

Обычные команды (CALL и RETURN) не подходят для вызова сопрограмм. Для этого подошла бы коман­да замены вершины стека на счетчик команд. Такая команда встречается редко, и в большинстве случаев ее приходится моделировать имеющимися командами.

5.3.4. Ловушки

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

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

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

Наиболее распространенные события, которые могут вызывать ловушки, - это переполнение и исчезновение значащих разрядов при операциях с плавающей точ­кой; переполнение при операциях с целыми числами; нарушения защиты; неопре­деляемый код операции; переполнение стека; попытка запустить несуществующее устройство ввода-вывода; попытка вызвать слово из ячейки с нечетным адресом и деление на 0.

Соседние файлы в папке Архитектура ЭВМ