14. Прерывания 14.1. Обзор прерываний

Лекции по предмету «Информатика»
Информация о работе
  • Тема: 14. Прерывания 14.1. Обзор прерываний
  • Количество скачиваний: 3
  • Тип: Лекции
  • Предмет: Информатика
  • Количество страниц: 7
  • Язык работы: Русский язык
  • Дата загрузки: 2014-05-05 16:09:50
  • Размер файла: 20.59 кб
Помогла работа? Поделись ссылкой
Информация о документе

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

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

14. Прерывания
14.1. Обзор прерываний
Это сложное понятие мы будем осваивать постепенно.
При выполнении программы в центральном процессоре может возникнуть ситуация, когда он должен временно приостановить (прервать) выполняемую программу и приступить к выполнению другой программы (связанной с возникшей ситуацией). Эта новая программа носит название: программа обработки прерывания (ПОП) — Interrupt Service Routine (ISR), interrupt handler.
Рассмотрим виды прерываний на примерах.
1) Исключения (exceptions).
При выполнении деления результат может не поместиться в аккумулятор. Тогда продолжать вычисления не имеет смысла. Происходит внутреннее прерывание (исключение). Начинает выполняться ISR, которая выводит соответствующее сообщение и передает управление операционной системе.
Другой пример: при выполнении может встретиться код несуществующей операции.
2) Внешние прерывания (External interrupts).
В корпусе процессора имеется два вывода: INTR и NMI. На них поступают сигналы от внешних устройств. Например, в компьютере имеется таймер, который через равные промежутки времени посылает ЦП сигнал прерывания на вход INTR. Процессор приостанавливает выполнение текущей программы и переходит к ISR, которая увеличивает на 1 содержимое ячейки ОЗУ, отведенной для подсчета времени.
На тот же вход INTR поступает сигнал от клавиатуры при нажатии на клавишу. Возникает вопрос, как процессор узнает, от какого устройства поступил сигнал? Для этого нужно детально изучить внешние прерывания. Однако уже сейчас полезно отметить: процессор воспринимает сигнал INTR только при условии, что IF = 1 (напомним, что IF — Interrupt Flag — это бит в регистре флагов). Если IF = 0, то процессор "глух" к сигналам на входе INTR.
IF — флаг управления (а не состояния, как те флаги, которые мы до сих пор рассматривали). Для его изменения есть две команды.

Запретить внешние прерывания cli IF ← 0
(CLear IF — очистить IF)

Разрешить внешние прерывания sti IF ← 1
(SeT IF — установить IF)

Не рекомендуется запрещать внешние прерывания сколько-нибудь длительное время, так как это собьет показания системных часов (ведь будут запрещены в том числе и прерывания от таймера).
Так как сигнал на входе INTR можно подавить, то внешние прерывания, вызывающие сигнал на этом входе, носят название маскируемых.
Но есть еще один вход: NMI — Non-Maskable Interrupt — немаскирумое прерывание. Сигнал на этом входе невозможно запретить сбросом флага IF. На этот вход поступает сигнал при падении напряжения в сети, при нарушении работы основной памяти.
3) Программные прерывания.
Механизм вызова ISR оказался настолько удобным, что его используют как альтернативу команде вызова подпрограммы (call). Мы убедимся далее, что зачастую программное прерывание называется прерыванием скорее по недоразумению, так как осуществляется по команде, содержащейся в программе. Это команда int N, где N — число от 0 до 255. Мы вскоре узнаем подробное описание этой команды и примеры.

Итак, один и тот же механизм используется в трех существенно различных ситуациях. Еще раз проведем классификацию.
Прерывания делятся на внешние и внутренние. Внешние прерывания делятся на маскируемые (сигнал от внешнего устройства на вход INTR) и немаскируемые (сигнал на вход NMI). Внутренние прерывания делятся на исключения и программные прерывания. В старших моделях семейства 80x86 для исключений проводится еще более тонкая дифференциация, но мы ее опустим.
Как должен осуществляться переход к ISR? При выполнении команды дальнего вызова подпрограммы в стеке сохранялись CS и IP. Может быть, для успешного возврата из подпрограммы этого будет достаточно и теперь? Нет! Сигнал от внешнего устройства с требованием прерывания появляется в непредсказуемые моменты времени. К чему это может привести, посмотрим на примере. Вот фрагмент программы:

cmp ax,3 ; Предположим, AX = 3, поэтому в результате ZF = 1 ; (должен произойти переход на метку m1)
ПРОИЗОШЛО ВНЕШНЕЕ ПРЕРЫВАНИЕ. ISR сбросила ZF!
je m1 ; Теперь ZF = 0 и перехода на m1 не произойдет.

В процессе исполнения программы обработки прерывания (которая может состоять из нескольких сотен команд) флаг ZF может многократно измениться. Возобновленная программа будет выполняться неправильно, если ZF = 0. Чтобы этого не произошло, следует сохранять не только регистры CS и IP, но и регистр флагов (Flags). Это излишне для команды int N, которую размещает в программе сам программист, но еще большая роскошь — вводить в схемы центрального процессора несколько механизмов прерываний. (Впрочем, для некоторых значений N сохранение регистра флагов имеет смысл.)

14.2. Программные прерывания
Программные прерывания осуществляются по команде int N, где N — число от 0 до 255. (Для вас должно быть очевидно, что в коде команды число N занимает байт.)
Вызов процедуры прерывания N-го типа int N описание ниже
call to INTerrupt procedure
Опишем работу команды.
1) в стеке сохраняются регистры: Flags↓, CS↓, IP↓;
2) сбрасываются флаги трассировки и разрешения прерывания: TF ← 0, IF ← 0.
3) в счетчик команд и регистр кодового сегмента копируется содержимое двух слов памяти, расположенных по физическим адресам 4*N и 4*N+2. IP ← (4*N), CS ← (4*N+2). В этих словах хранится адрес ISR. (CS более значимо и поэтому хранится по старшему адресу).
Еще раз подчеркнем, что это описание относится только к процессору 8086. Для процессоров старших моделей имеются свои особенности, с которыми уместно познакомиться позднее.
Начинается выполнение ISR. Она заканчивается командой возврата из процедуры обработки прерывания.
Возврат из прерывания iret IP↑, CS↑, Flags↑
Interrupt RETurn

Извлечение из стека происходит в обратном порядке по сравнению с занесением. Возобновляется выполнение прерванной программы.
Итак, для прерывания типа N в словах с адресами 4*N и 4*N+2 хранятся новые CS и IP. В математике столбцы чисел называются векторами. Из-за этой внешней аналогии пару слов (4N) и (4N+2) называют вектором прерывания.
Выполнение ISR обычно включает следующие действия:
• установка флага IF (он был сброшен командой int N);
• сохранение используемых регистров в стеке;
• выполнение команд тела процедуры;
• восстановление из стека ранее сохраненных регистров;
• выполнение команды iret.
Разумеется, эта схема соблюдается не всегда. Программе, обрабатывающей ошибку деления, не нужно сохранять в стеке используемые регистры, не нужно возвращаться в прерванную программу.
Обращение к системным программам, входящим в состав DOS и BIOS организовано через вектора прерываний.
Пример. int 12h — получить размер ОЗУ (conventional memory).
вход — нет;
выход — в AX количество килобайт памяти (в пределах 640K).
Сейчас эта информация совершенно бесполезна (современные компьютеры обладают оперативной памятью, заведомо превышающей 1 Мб).
Посмотрим, как устроена соответствующая ISR. Следующее изложение относится к операционным системам Windows 95 и Windows 98. В Windows XP код ISR другой.
1) Вычислим адрес вектора прерываний.
12h * 4 = 48h — адрес IP, 12h * 4 + 2 = 4Ah — адрес CS.
2) Прочитаем вектор. Для этого в панели данных перейдем к адресу 0:48 и отобразим данные как слова.
0000:0048 F841 F000
Итак, IP = F841, CS = F000. Соответственно, адрес ISR есть F000:F841. Программа находится в 15-м блоке памяти, т.е. в ПЗУ. Это программа BIOS.
3) Alt+F10 → Follow (Use data at cursor as new address for code or data display — использовать данные, на которые указывает курсор, как новый адрес для отображения кода или данных)→ Far Code (Set code pane to far address at cursor — установить в панели на дальний адрес под курсором).
Произойдет переход в панель кода.
4) Проанализируем код.
F000:F841 FB sti ; Разрешить внешние прерывания
F000:F842 1E push ds ; Сохранить используемый регистр DS
F000:F843 6A40 push 0040 ; Настроить DS на
F000:F845 1F pop ds ; область данных BIOS
F000:F846 A11300 mov ax,[0013] ; В AX содержимое 0:413
F000:F849 1F pop ds ; Восстановить регистр DS
F000:F84A CF iret ; Возврат из прерывания
Итак, реализована уже знакомая нам по одному из примеров главы 3 процедура.

14.3. Команды программного прерывания.
Мы уже изучили последовательность действий, которые совершает ЦП при выполнении команды int N. Эта команда имеет еще две разновидности. Опишем их, но сначала для удобства напомним описание команды int N.
Прерывание типа N
(код команды занимает два байта: CD N) int N Flags↓, CS↓, IP↓
TF ← 0, IF ← 0
IF ← (4*N), CS ← (4*N+2)
флаги состояния не изменяются

Однобайтное прерывание
(код команды занимает один байт: CC) int Действия, как для int 3
флаги состояния не изменяются

Прерывание при знаковом переполнении into Если флаг OF = 1, то действия, как для int 4
флаги состояния не изменяются

Однобайтная команда int используется отладчиками. Здесь важен не тип прерывания (3), он мог быть и другим, а то, что команда однобайтная. Когда в программе на одной из команд указывается точка останова, то отладчик заменяет код исходной команды кодом команды int 3, т.е. CC, а исходный код сохраняет. При прогоне программы возникает прерывание при выполнении команды int 3. Прогон приостанавливается, исходная команда восстанавливается, и пользователь может изучить состояние программы. Но так как имеются команды, код которых занимает один байт (например, inc bx), то код замещающей команды прерывания не может превышать один байт. Иначе будет «затерт» код следующей команды.
Команду into разберем позже (в следующей главе).

14.4. Распределение векторов прерываний
В команде int N тип прерывания N лежит в диапазоне от 0 до 255 (от 0 до FFh). Стало быть, вектора прерываний расположены в диапазоне от 0 до 4*FF+2 = 4*(100h-1)+2 = 3FEh. Начиная с адреса 400h, расположена область данных BIOS. Мы не будем приводить полную таблицу векторов, а посмотрим ее начальный фрагмент.
Адрес Содержимое Тип Описание
0 IP 0 Ошибка при делении
2 CS
4 IP 1 Пошаговый режим выполнения
6 CS
8 IP 2 Немаскируемое прерывание (NMI)
A CS
C IP 3 Однобайтовая команда прерывания (int)
E CS
10 IP 4 Знаковое переполнение (into)
12 CS

4*N IP N
4*N+2 CS

3FC IP 255=FF
3FE CS
400 Область данных BIOS

Значения CS и IP здесь не указаны, так как они зависят от версии DOS и BIOS. В этом и заключается удобство использования векторов прерываний: они составляют таблицу с адресами подпрограмм. Достаточно знать к какой строке таблицы обращаться, т.е. знать тип прерывания, а содержимое таблицы знать не надо.
Приведено назначение нескольких первых векторов. В целом же вектора распределены так.
0h – 1Fh — исключения и функции BIOS
20h – 5Fh — для DOS
60h – 66h — для пользовательских прерываний
В некоторых векторах может храниться не адрес ISR, а адрес какой-нибудь таблицы, например таблицы видеопараметров.
Программное прерывание 10h предназначено для управления дисплеем. Сразу возникает вопрос: как можно в одно программное прерывание включить разнообразные функции для дисплея? На самом деле вектор 10h хранит лишь адрес диспетчера функций управления дисплеем. В регистре AH передается номер функции. В других регистрах передаются параметры функции.
Пример. В некоторых клавиатурных драйверах переход на кириллицу сопровождается появлением рамки красного цвета. Эта рамка окаймляет окно MS DOS только в полноэкранном режиме. (Для переключения в полноэкранный режим и обратно нужно использовать клавиатурную комбинацию Alt+Enter.) Научимся получать этот эффект. Для этого используется прерывание 10h, функция 10h, подфункция 01h — установить цвет края экрана. Номер цвета передается в регистре BH. Таблицу цветов приводить не будем. Достаточно знать, что 04h — красный цвет, а 00h — черный. Наберем в отладчике программный фрагмент.

cs:0100► mov ax,1001
cs:0103 mov bh,04
cs:0105 int 10
cs:0107 mov bh,0
cs:0109 int 10
cs:010B nop
При выполнении программы до смещения 107 рамка экрана становится красной, далее (при выполнении до 10b) она приобретает прежний цвет.

14.5. Системные вызовы в MS DOS.
Аппарат программных прерываний используется в MS DOS для вызова системных функций.
Завершение com-программ осуществляется с помощью команды int 20h. До сих пор мы заканчивали программы, набираемые в отладчике, командой nop — просто чтобы знать адрес, до которого нужно выполнять прогон программы. Команда int 20h обеспечивает корректное завершение работы программы.
Задача. Создайте с помощью отладчика две программы red.com и black.com. Первая программа делает рамку экрана красной, а вторая — черной. Запустите на выполнение сначала red.com, затем black.com.

Функции операционной системы вызываются с помощью команды int 21h. Это диспетчер системных функций. Номер функции передается в регистре AH. В другие регистры программист помещает входные параметры системной функции.
1. Вместо устаревшего системного вызова int 20h фирма Microsoft настоятельно рекомендует применять функцию 4Сh. Описание этой функции имеет вид:
Вход: AH = 4Ch — номер функции;
AL — код возврата.
Поясним, зачем нужен код возврата. В операционной системе MS DOS код возврата помещается в системную переменную ERRORLEVEL. Значение этой переменной может быть проанализировано, например, в командном файле. В зависимости от этого значения можно запустить ту или иную программу. Принято соглашение, что если программа выполнилась нормально, то ее код возврата равен нулю.
Пример. При запуске программы на выполнение можно указать в командной строке параметры. Например, вызов bcc.exe без параметров приведет к выдаче на экран справочных сведений. Вызов bcc.exe –v prog.c произведен с двумя параметрами: -v и prog.c. В совокупности они образуют хвост командной строки.
Создадим файл prim.com, возвращающий в операционную систему 0, если вызов программы произошел без параметров, и число, отличное от нуля, если хвост командной строки не пуст. Воспользуемся тем, что по смещению 80h хранится длина хвоста командной строки (подробнее мы обсудим это в следующей главе). Эта длина и будет кодом возврата.
Итак, введите в отладчике следующий код для pr.com:
mov al,[80]
mov ah,4C
int 21
А теперь наберите текст командного файла prim.bat:
pr.com %1
IF ERRORLEVEL 1 GOTO red_border
@echo no parameters
black.com
GOTO exit
:red_border
@echo parameters
red.com
:exit

Отметим несколько моментов.
1) В первой строке %1 означает первый параметр. Если мы введем
prim.bat aaa bb
то aaa станет первым параметром %1, а bb — вторым параметром %2. Они разделены пробелами. Нам достаточно проверить наличие хотя бы одного параметра.
2) Во второй строке нет символа отношения между ERRORLEVEL и 1. Подразумевается, что это «больше или равно».
3) @echo текст выводит на экран текст.
4) Двоеточие ставится перед меткой, а не после.
Пример, конечно, надуманный. Но он дает основу для автоматизации работы пользователя, когда надо запускать на выполнение несколько программ одну за другой. При этом можно осуществлять «ветвление» в зависимости от результата работы программы. Это пригодится нам уже в следующей главе.

2. Функция вывода строки на экран.
Вход: AH = 09h — номер функции;
DS:DX — адрес строки.
Строка заканчивается символом $, т.е. символ $ (код ASCII 24h) является терминатором (завершителем) строки.

cs:0100 B409 mov ah,09
cs:0102 BA0C01 mov dx,010C
cs:0105 CD21 int 21
cs:0107 B8004C mov ax,4C00
cs:010A CD21 int 21
По адресу 10C введем строку Example$
Сохраним программу в файле msg.com (стартовый адрес 100h, размер 14h).
Прогон программы в отладчике осуществляется нажатием F9. Далее переключаемся на пользовательский экран: F10 → Window → User screen. Возвращаем экран отладчика нажатием клавиши Esc.

3. Вывод на экран одиночного символа.
Вход: AH = 02h — номер функции;
DL — код символа.
Задача. Наберите в отладчике программу, выводящую фразу: "Товар стоит 1000$." Сделайте два решения:
1) только циклический вызов функции 02h;
2) один раз вызвать функцию 09h и дважды функцию 02h (код точки — 2Eh).
Каждый раз создавайте .com-файл и запускайте его автономно.