- •7. Ввод-вывод
- •7.1. Доступ к устройствам ввода-вывода
- •7.2. Прерывания
- •7.2.1. Аппаратное обеспечение для поддержки прерываний
- •7.2.2. Запрет и разрешение прерываний
- •7.2.3. Обслуживание нескольких устройств
- •7.2.4. Управление запросами устройств
- •7.2.5. Исключения
- •7.2.6. Прерывания в операционных системах
- •7.3. Механизм прерываний процессора Pentium
- •7.4. Прямой доступ к памяти
7.2. Прерывания
В примере на рис. 7.4 программа выполняет цикл ожидания, постоянно проверяя состояние устройства. В течение этого времени процессор не делает никакой полезной работы. Однако во многих случаях в течение времени ожидания готовности устройства ввода-вывода процессор мог бы выполнять другие задачи. Для этого нужно так организовать совместную работу процессора и внешнего устройства, чтобы это устройство само оповещало процессор о своей готовности к пересылке данных. Такое оповещение выполняется с помощью специального сигнала, называемого прерыванием. Для прерываний обычно выделяется как минимум одна управляющая линия шины, называемая линией запроса прерывания. Поскольку при использовании прерываний процессору не нужно постоянно проверять состояние внешних устройств, он может использовать периоды ожидания для выполнения других полезных функций. Благодаря этому процессор никогда не простаивает.
Пример 7.2______________________________________
Рассмотрим задачу, для выполнения которой нужно произвести некоторые вычисления и напечатать результаты на принтере, затем произвести другие вычисления и снова распечатать результаты — и так несколько раз. Предположим, что выполняющая эту задачу программа состоит из двух подпрограмм, COMPUTE и PRINT. Подпрограмма COMPUTE генерирует n выходных строк, которые должны быть напечатаны подпрограммой PRINT.
Для реализации указанной задачи программа может многократно выполнять подпрограмму COMPUTE, а затем подпрограмму PRINT. Принтер за один раз принимает только одну строку текста. Поэтому подпрограмма PRINT должна отослать одну строку текста, подождать, пока он будет напечатан, отослать следующую строку и т. д. Недостатком этого подхода является то обстоятельство, что процессор тратит немало времени в ожидании готовности принтера. Общую скорость выполнения программы можно значительно увеличить путем чередования процессов печати и вычисления, то есть за счет выполнения во время печати подпрограммы COMPUTE. Делается это следующим образом. Сначала выполняется подпрограмма COMPUTE, которая генерирует n первых строк текста, затем — подпрограмма PRINT, отправляющая первую строку на принтер. Однако вместо того чтобы дожидаться окончания процесса печати строки, подпрограмма PRINT может временно приостановить свое выполнение и передать управление программе COMPUTE. Когда принтер будет готов к печати следующей строки, он оповестит об этом процессор, выдав сигнал запроса прерывания. В ответ процессор прервет выполнение подпрограммы COMPUTE и передаст управление подпрограмме PRINT. Подпрограмма PRINT отправит на принтер вторую строку и снова приостановит свою работу. Прерванная программа COMPUTE продолжит работу с точки прерывания. Этот процесс может продолжаться до тех пор, пока не будут напечатаны все n строк и подпрограмма PRINT не закончит свою работу. Когда следующие n строк будут готовы для печати, выполнение подпрограммы PRINT начнется сначала. И если на формирование подпрограммой COMPUTE n строк текста понадобится больше времени, чем на их печать, процессор все время будет занят полезными вычислениями.
Этот пример иллюстрирует концепцию прерываний. Программа, выполняемая в ответ на запрос прерывания, называется программой обработки прерываний. В нашем случае роль таковой выполняет подпрограмма PRINT. Прерывания очень похожи на вызовы подпрограмм. Предположим, что запрос прерывания поступает во время выполнения команды i (рис. 7.5). Процессор завершает выполнение этой команды, а затем загружает в счетчик команд адрес первой команды программы обработки прерываний. Для упрощения задачи предположим, что этот адрес аппаратно закреплен в процессоре. После выполнения программы обработки прерываний процессор должен вернуться к команде i + 1. Для этого перед вызовом программы обработки прерывания содержимое регистра PC должно быть временно сохранено в памяти. Команда возврата из прерывания, расположенная в конце программы обработки прерывания, загрузит этот сохраненный адрес в регистр PC, в результате чего выполнение будет продолжено с команды i + 1. Во многих компьютерах адрес возврата сохраняется в стеке процессора. Но он может быть сохранен и в другом месте, например, в специально для него предназначенном регистре.

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