Реклама:

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

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

Чтобы понять, как происходят прерывания, рассмотрим обычный пример: компьютеру нужно вывести на терминал строку символов. Программа сначала собирает в буфер все символы, предназначенные для вывода на экран, инициализирует глобальную переменную ptr, которая должна указывать на начало буфера, и делает вторую глобальную переменную count равной числу символов, выводимых на экран. Затем программа проверяет, готов ли терминал, и, если готов, выводит на экран первый символ (например, используя регистры, показанные на рис. 5.20). Начав процесс ввода-вывода, центральный процессор освобождается и может запустить другую программу или сделать что-либо еще.

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

Действия аппаратного обеспечения:

1. Контроллер устройства нагружает линию прерывания на системной шине.

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

3. Когда контроллер устройства обнаруживает, что сигнал прерывания подтвержден, он помещает небольшое целое число на информационные линии, чтобы "представиться" (то есть, показать, что за устройство является источником прерывания). Это число называется вектором прерываний1.

4. Центральный процессор считывает вектор прерываний с шины и временно его сохраняет.

5. Центральный процессор помещает в стек счетчик команд и слово состояния программы.

6. Центральный процессор определяет местонахождение нового счетчика команд, используя вектор прерывания в качестве индекса в таблице в нижней части памяти. Если, например, размер счетчика команд составляет 4 байта, тогда вектор прерываний п соответствует адресу An. Новый счетчик команд указывает на начало программы обработки прерываний для устройства, ставшего источником прерывания. Часто помимо этого загружается или изменяется слово состояния программы (например, чтобы блокировать дальнейшие прерывания).

Дальнейшие действия выполняются программно:

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

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

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

1 Автор не совсем прав: здесь речь должна идти о номере прерывания. Каждому типу прерывания соответствует свой номер. Термин "вектор прерываний" используется в случае, когда по номеру прерывания находится адрес программы обработки прерывания, и этот адрес представляется не одним значением, а несколькими, то есть приходится инициализировать более одного регистра. Другими словами, адрес представляется не скалярной величиной, а многомерной, векторной. - Примеч. паучп. ред.

10. Если происходит ошибка ввода-вывода, на этом этапе ее нужно обработать.

11. Глобальные переменные ptr и count обновляются. Первая увеличивается на 1, чтобы показывать на следующий байт, а вторая уменьшается на 1, чтобы указать, что осталось вывести на 1 байт меньше. Если count все еще больше 0, значит, еще не все символы выведены на экран. Тот символ, на который в данный момент указывает ptr, копируется в выходной буферный регистр.

12. В случае необходимости выдается специальный код, который сообщает устройству или контроллеру прерывания, что прерывание обработано.

13. Восстанавливаются все сохраненные регистры.

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

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

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

Здесь существует два подхода. Первый - для всех программ обработки прерываний сначала (даже до сохранения регистров) предотвратить последующие прерывания - в этом случае прерывания будут происходить строго поочередно. Однако это может привести к проблемам с устройствами, которые не могут долго простаивать. Например, на линию связи, поддерживающую скорость передачи 9600 бит в секунду, символы поступают каждые 1042 микросекунды. Если первый символ окажется необработанным, когда поступит второй, данные будут потеряны.

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

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

Поскольку сами программы обработки прерываний могут прерываться, единственно возможный способ точно управлять ситуацией - сделать так, чтобы все прерывания были прозрачными. Рассмотрим простой пример с несколькими прерываниями. Пусть компьютер имеет три устройства ввода-вывода: принтер, диск и линию 118232 с приоритетами 2, 4 и 5 соответственно. Изначально (£ = О, где Ь - время) работает пользовательская программа. При £ = 10 принтер неожиданно инициирует прерывание. Запускается программа обработки прерывания (1811) от принтера, как показано на рис. 5.28.

Прерывания5

Рис. 5.28. Пример с несколькими прерываниями. Последовательность действий

При £ = 15 прерывания требует линия 118232. Так как линия 118232 имеет более высокий приоритет (5), чем принтер (2), инициируется обработка этого прерывания. Состояние машины, при котором работает 1811 принтера, сохраняется в стеке, и начинается выполнение программы обработки прерывания линии 118232.

Немного позже, при £ = 20, диск завершает свою работу и сигнализирует об этом прерыванием. Однако его приоритет (4) ниже, чем приоритет работающей в данный момент программы обработки прерываний (5), поэтому центральный процессор не подтверждает прием сигнала прерывания, и диск вынужден ждать. При £ = 25 заканчивает работать 1811 линии 118232, и машина возвращается в то состояние, в котором она находилась до прерывания от линии 118232, то есть в состояние, соответствующее работе 1811 принтера с приоритетом 2. Как только центральный процессор переключается на приоритет 2, еще до выполнения первой команды, диск с приоритетом 4 совершает прерывание, и запускается 1811 диска. После ее завершения снова продолжается программа обработки прерываний от принтера. Наконец, при £ = 40 все программы обработки прерываний завершаются, и выполнение пользовательской программы начинается с того места, на котором она прервалась.

Со времен процессора 8088 все процессоры Intel имеют два уровня (приоритета) прерываний: маскируемые и немаскируемые прерывания. Немаскируемые прерывания обычно используются только для сообщения об очень серьезных ситуациях, например об ошибках четности в памяти. Для всех устройств ввода-вывода имеется единственное маскируемое прерывание.

Когда устройство ввода-вывода требует прерывания, центральный процессор использует вектор прерывания при индексировании таблицы из 256 элементов, чтобы найти адрес программы обработки прерываний. Элементы таблицы представляют собой 8-байтные дескрипторы сегмента. Таблица может начинаться в любом месте памяти. Глобальный регистр указывает на ее начало.

При наличии только одного уровня прерываний у центрального процессора нет возможности сделать так, чтобы высокоприоритетное устройство прерывало работу среднеприоритетной программы обработки прерываний, пока этому мешает низкоприоритетное устройство. Для решения проблемы центральные процессоры Intel обычно используют внешний контроллер прерываний (например, 8259А). При первом прерывании (например, с приоритетом п) работа процессора приостанавливается. Если после этого происходит еще одно прерывание с более высоким приоритетом, контроллер прерывания инициирует прерывание во второй раз. Если же второе прерывание обладает более низким приоритетом, оно не инициируется до окончания первого. Чтобы эта система работала, контроллер прерываний должен каким-либо образом узнавать о завершении текущей программы обработки прерываний. Поэтому когда полностью завершается обработка текущего прерывания, центральный процессор должен посылать контроллеру прерываний специальную команду.

Перехват исключений || Оглавление || Ханойская башня