Что такое перехват прерываний
Interrupt 19 Capture
Опция BIOS Interrupt 19 Capture (Перехват прерывания 19) входит в категорию опций, предназначенных для управления процессом загрузки системы. Ее обычные значения – Enabled (Включено) и Disabled (Выключено).
Принцип работы
При загрузке компьютера в самом конце процедуры проверки оборудования POST происходит вызов прерывания 19h. Это прерывание предназначено для чтения первого сектора загрузочного устройства, в котором размещается код, инициирующий загрузку операционной системы компьютера.
Обычно это прерывание обрабатывается BIOS материнской платы, однако в ряде случаев BIOS может изменить порядок его обработки. Эта возможность оказывается полезной в том случае, если в системе установлены платы расширения дополнительных контроллеров, предназначенных для подключения жестких дисков и иных накопителей. Обычно такие контроллеры позволяют работать с накопителями с интерфейсом IDE/SATA или SCSI, а также могут подключать дисковые массивы (RAID). В таком случае может возникнуть потребность в загрузке с одного из накопителей, подключенных к подобному контроллеру. Однако в стандартной ситуации это оказывается невозможным, поскольку BIOS по умолчанию передает управление операционной системе, установленной на одном из накопителей, подключенных к стандартным разъемам IDE/SATA материнской платы.
Описываемая функция дает возможность переключить обработку прерывания 19h c BIOS материнской платы на BIOS установленных в системе дополнительных контроллеров IDE/SATA/SCSI. В случае включения опции прерывание 19h будет перехватываться BIOS этих контроллеров, что позволит осуществить загрузку операционной системы с дисков, подключенных к ним. Кроме того, в некоторых случаях пользователь может получить доступ к встроенной утилите настройке этих контроллеров, хранящейся в их BIOS.
Отключение опции не позволит BIOS дополнительных контроллеров перехватывать прерывание 19h. Это приведет к тому, что будет невозможна загрузка с накопителей, подключенных к дополнительным адаптерам IDE/SATA/SCSI.
Стоит ли включать?
Если у вас в компьютере установлены дополнительные контроллеры IDE/SATA/SCSI, к которым, в свою очередь, подключены накопители, с которых должна осуществляться загрузка операционной системы, то включение опции BIOS Interrupt 19 Capture является обязательным. Кроме того, опцию необходимо включить также и в том случае, если вы хотите получить доступ к встроенной утилите настройки дополнительного контроллера IDE/SATA/SCSI.
Если вы не используете подобные контроллеры или не собираетесь загружаться с накопителей, подключенных к ним, то следует выключить опцию, установив ее значение Disabled. В этом случае загрузка будет производиться с накопителей, подключенных к разъемам IDE/SATA, находящимся на материнской плате.
Перехват прерываний и резидентные программы
Большая часть всех функциональных возможностей MS-DOS заключается в обработке разнообразных аппаратных и особенно программных прерываний. В частности, обращение к многочисленным системным функциям MS-DOS выполняется с помощью вызова программного прерывания int 21h.
Тем важнее оказывается тот факт, что в MS-DOS программа пользователя имеет возможность перехватить любое прерывание, т.е. установить свой обработчик этого прерывания. Фактически для этого достаточно записать адрес нового обработчика по соответствующему адресу памяти. Имеются системные функции для запоминания адреса прежнего обработчика и установки нового.
Перехват аппаратных прерываний позволяет программе оперативно реагировать на различные события. Особенно часто перехватываются прерывания от таймера, что позволяет выполнять некоторое действие регулярно, через заданный интервал времени, (скажем, отображать текущее время) или же выполнить его один раз в заранее запланированный момент, а также прерывания от клавиатуры, позволяющие выполнить действие при нажатии определенной комбинации клавиш. Например, одно время были популярны резидентные калькуляторы, которые появлялись на экране при нажатии заданных клавиш. Еще один пример такого рода – программы, переключающие русский/латинский регистры клавиатуры.
Перехват программных прерываний позволяет программе модифицировать выполнение любой функции MS-DOS. Выше говорилось об использовании перехвата прерываний для определения реакции программы на нажатие Ctrl+Break и на критические ошибки. Еще одним примером может служить системная программа SHARE.EXE, которая обеспечивает корректное разделение файлов между процессами. Эта программа перехватывает основные файловые функции MS-DOS, чтобы отследить все открытия и закрытия файлов и установку/снятие блокировок. На основании этой информации модифицированные функции открытия, чтения и записи файла определяют, разрешена ли запрошенная операция.
Программы, использующие перехват прерываний, можно разбить на два класса.
· Нерезидентные программы, которые после завершения своей работы возвращают управление и всю занимаемую память системе. Такие программы перехватывают прерывания только на время своей работы и должны обязательно восстановить стандартную обработку прерываний при своем завершении. Это требование касается не только нормального завершения, но и завершения по Ctrl+Break и по критической ошибке. В противном случае при последующем возникновении прерывания управление будет передано по адресу уже не существующего в памяти обработчика, а это крах.
· Резидентные программы представляют собой обработчики прерываний, остающиеся в памяти и после завершения загрузившего их процесса, вплоть до перезагрузки системы. Таким образом, резидентные программы могут оказывать влияние на работу MS-DOS и всех запускаемых программ.
К какому классу должна принадлежать упомянутая выше программа SHARE.EXE?
Не будет ошибкой сказать, что резидентные программы в некоторой степени превращают однозадачную MS-DOS в многозадачную систему. В данном случае реализуется примитивная форма фоново-оперативной диспетчеризации, в которой резидентные программы играют роль оперативных процессов, а обычная работа MS-DOS осуществляется в фоновом режиме.
К сожалению, в MS-DOS нет надежных, поддерживаемых системой средств для создания оперативных процессов. Вместо этого есть только возможность перехвата прерываний и еще некоторые полезные, но разрозненные функции, которые дают прикладному программисту возможность «вручную» реализовать многозадачность, но не гарантируют корректности результата.
Среди проблем, которые приходится решать разработчику резидентных программ, можно назвать несколько наиболее типичных.
· При установке резидентной программы следует проверить, не была ли она уже установлена, поскольку двукратный перехват прерываний одной и той же программой обычно приводит к неверной работе программы. Такую проверку можно выполнить различными способами. Чаще всего используют вызов определенного программного прерывания, которое должно вернуть характерный результат, если оно уже перехвачено.
· В MS-DOS нет понятия контекста программы и тем более нет средств переключения контекста. Если работа резидентной программы может привести к изменению таких системных данных, как текущие диск и каталог, информация о последней случившейся ошибке, идентификатор текущего процесса и т.п., то эта программа должна позаботиться о сохранении и восстановлении этих данных, чтобы не помешать нормальной работе фонового процесса.
· Почти все функции MS-DOS нереентерабельны, причем даже не по отдельности, а в совокупности, т.е. вызов одной из этих функций при незавершенном выполнении другой может привести к краху системы. Это не вызывает затруднений, пока MS-DOS работает как однозадачная система. Однако активизация резидентной программы может произойти во время выполнения функции DOS, вызванной из фоновой программы. Если резидентная программа также вызовет какую-либо системную функцию (а без этого невозможно, например, работать с файлами), то последствия будут плачевны. Способы обойти это затруднение существуют, но по своей запутанности они больше похожи на рецепты алхимиков.
Дата добавления: 2015-09-07 ; просмотров: 542 ; ЗАКАЗАТЬ НАПИСАНИЕ РАБОТЫ
Что такое перехват прерываний
Перейдем к рассмотрению более сложного случая, когда обработчик прерываний должен использовать уже занятый вектор прерываний. В этом случае требуется выполнить перехват прерываний – запись в вектор прерываний стартового адреса нового обработчика. Это нетрудно сделать, используя рассмотренный ранее системный вызов “int 21h”, функция 25h. Но дополнительная задача заключается в том, что обычно требуется сохранить прежнее содержимое вектора прерываний для того, чтобы прежний обработчик прерываний можно было бы впоследствии инициировать.
Для чтения прежнего содержимого вектора прерываний используется системный вызов “int 21h”, функция 35h. Перед выполнением вызова программа должна поместить в регистр AL номер прерывания. В результате выполнения вызова регистры ES и BX содержат соответственно адрес-сегмент и адрес-смещение, находящиеся в векторе прерываний. Далее эти адреса могут быть переписаны для сохранения в любое место ОП.
Инициирование прежнего обработчика прерываний может потребоваться в двух случаях. Во-первых, в том случае, если новый обработчик прерываний не заменяет, а лишь расширяет функции, выполнявшиеся прежним обработчиком. При этом после того, как новый обработчик выполнится, он должен передать управление старому обработчику. Во-вторых, часто обработчик прерываний должен находиться в ОП не до конца работы системы. В этом случае перед тем, как освободить память, необходимо восстановить старый обработчик прерываний. Это нетрудно сделать с помощью системного вызова “int 21h”, функция 25h. Рассмотрим реализацию первого случая.
Пример. Следующая резидентная программа “дополняет” обработку прерывания с номером 0. Системный обработчик данного прерывания-исключения прекращает выполнение текущей программы, если ее команда выполнила деление на 0. Наш обработчик спрашивает пользователя о желании завершить программу. В случае нажатия клавиши y (или Y) выполнение программы прекращается. При нажатии любого другого символа выполнение программы продолжается.
; Резидентная программа выполняет обработку исключения 0 (деление на 0)
cr equ 0dh ; Код ASCII возврата каретки
lf equ 0ah ; Код ASCII перевода строки
absolute 2ch ; Следующий байт имеет адрес-смещение 2ch
Blocokr resw 1 ; Адрес-сегмент блока окружения
segment code ; Виртуальный сегмент кода
Start: jmp Init ; Переход на инициализацию
Old dd 0 ; Прежнее содержимое вектора пр-й
Begin: sti ;Разрешить маскируемые прерывания
push ax ; Сохранение содержимого
push dx ; регистров
pushf ; Сохранение регистра флагов
mov ax, cs ; DS будет адресовать данные
mov ds, ax ; резидентной программы
mov dx, Msg ; DX ß адрес строки-сообщения
mov ah, 9 ; Вывод строки
mov ah,1 ; Ввод символа с
int 21h ; клавиатуры
or al, 20h ; Перевод символа на нижний регистр
popf ; Восстановление регистра флагов
pop ds ; Восстановление содержимого
jmp far [Old] ; Вызов прежнего обработчика
.Exit: mov ah, 2 ; Перевод
popf ; Восстановление регистра флагов
pop ds ; Восстановление содержимого
iret ; Возврат из прерывания
; Инициализационная часть программы
Init: mov ax, 3500h ; Сохранение прежнего содержимого
int 21h ; вектора 0 в регистрах ES и BX
mov [Old], bx ; А затем
mov [Old+2], es ; в поле Old
mov ax, 2500h ;Запись стартового адреса обработчика
mov dx, Begin ; в вектор прерываний
int 21h ; с номером 0
mov ah, 49h ; Освобождение области памяти,
mov es, [Blocokr] ; занимаемой
int 21h ; блоком окружения
mov dx, Init ; Возврат в DOS, оставшись
int 27h ; резидентным
Как и предыдущая программа, данная программа состоит из инициализационной и резидентной частей. Инициализационная часть начинает свою работу с сохранения прежнего содержимого вектора прерываний 0 в двойном слове ОП с меткой Old. Затем она помещает в вектор 0 стартовый адрес нашего обработчика прерываний и сокращает объем занимаемой им памяти. В завершении инициализационная часть выполняет возврат в DOS, оставив в памяти обработчик прерываний.
Обработчик прерываний (резидентная часть) запускается в результате прерывания-исключения с номером 0. В начале своего выполнения он разрешает маскируемые внешние прерывания, а также сохраняет в стеке используемые им регистры. Обратите внимание, что среди сохраняемых регистров находится и регистр флагов. Это делается для того, чтобы прежний обработчик прерываний получил такое содержимое этого регистра, которое установила ранее программа. (На тот случай, если некоторые флаги используются для передачи информации на вход обработчика.)
Далее резидентная часть выводит на экран вопрос о желании прекратить выполнение программы, выполнившей деление на 0. Ответ пользователя (один символ) переводится в строчный символ. Такой перевод выполняется установкой единственного бита 5, которым отличаются коды строчной и прописной одноименных букв. Если пользователь не желает прекращать выполнение программы, то выполняется возврат из прерывания.
Иначе – управление передается системному обработчику. Это делается с помощью команды jmp, выполняющей безусловный переход на стартовый адрес этого обработчика. Рассмотрим внимательно соответствующий программный оператор:
jmp far [Old] ; Вызов прежнего обработчика
Во-первых, данный оператор выполняет межсегментный переход. Об этом говорит наличие вспомогательного псевдооператора far (дальний). Кроме дальних переходов в программе возможны очень близкие переходы (не более чем на 128 байт) и близкие переходы – в пределах сегмента кода. Для задания таких переходов используются, соответственно, псевдооператоры short и near. По умолчанию оператор jmp выполняет очень близкий переход и поэтому оператор short можно не записывать. Запись оператора near аналогична записи оператора far – между jmp и операндом.
Во-вторых, рассматриваемый оператор выполняет косвенный переход. Об этом говорит наличие имени Old, заключенного в квадратные скобки. Данное имя является не именем процедуры, а именем поля данных длиной два слова (четыре байта). В первом из этих слов находится адрес-смещение первого байта запускаемой процедуры, а во втором слове – адрес-сегмент этого байта. Таким образом, поле Old содержит стартовый логический адрес вызываемой процедуры.
Закономерен вопрос: как системный обработчик возвратит управление (если пожелает) в прерванную программу? Ответ: обычным способом, то есть с помощью команды iret. Это объясняется тем, что системный обработчик «наследует» от нашего обработчика стек прерванной программы, в который был помещен ранее адрес возврата (в момент прерывания).
Для проверки работоспособности рассмотренного обработчика прерываний необходимо: после того, как приведенная выше программа будет выполнена (сделав обработчик прерываний резидентным), запустить на выполнение простейшую прикладную программу, выполняющую деление на нуль в бесконечном цикле.
Если резидентная программа полностью заменяет систему в обработке каких-то типов прерываний, то по истечению какого-то времени у пользователя (или у прикладной программы) может возникнуть желание вернуться к системной обработке этих прерываний. Для этого следует выполнить следующие три действия:
1) закрыть файлы, открытые резидентной программой;
2) восстановить векторы прерываний так, чтобы они указывали на системные обработчики;
3) освободить память, занимаемую резидентной программой.
Перечисленные действия должна выполнить сама резидентная программа при получении ею команды о завершении. Например, если резидентная программа выполняет обработку прерываний от клавиатуры, то код одной из клавиш (комбинации клавиш) может использоваться в качестве такой команды.
Для восстановления векторов прерываний можно использовать рассмотренные ранее системные вызовы “int 21h” (функции 35h и 25h). Первый из этих вызовов позволяет запомнить, а второй – восстановить прежнее содержимое вектора прерывания.
Для освобождения памяти, занимаемой резидентной программой, можно воспользоваться системным вызовом “int 21h” (функция 49h), который требует задания в регистре ES адреса-сегмента области резидентной программы. Так как адрес-сегмент резидентной программы находится во время ее выполнения в регистре CS, следующий фрагмент программы показывает, как можно осуществить такой вызов:
push cs ; Копирование CS
mov ah, 49h ; Освобождение
Перехват прерываний
Перехват прерываний в работе процессора во время выполнении текущей программы. Типы и особенности развития данных ситуаций. Практические примеры обработчика программного прерывания. Определение значения нескольких векторов, установление нового значения.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | контрольная работа |
Язык | русский |
Дата добавления | 13.08.2011 |
Размер файла | 81,9 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
1. Перехват прерываний
В архитектуре процессоров 80×86 предусмотрены особые ситуации, когда процессор прекращает (прерывает) выполнение текущей программы и немедленно передает управление программе-обработчику, специально написанной для обработки этой конкретной ситуации. Такие особые ситуации делятся на два типа: прерывания и исключения, в зависимости от того, вызвало ли эту ситуацию какое-нибудь внешнее устройство или выполняемая процессором команда. Исключения делятся далее на три типа: ошибки, ловушки и остановы, в зависимости от того, когда по отношению к вызвавшей их команде они происходят. Ошибки происходят перед выполнением команды, так что обработчик такого исключения получит в качестве адреса возврата адрес ошибочной команды (начиная с процессоров 80286), ловушки происходят сразу после выполнения команды, так что обработчик получает в качестве адреса возврата адрес следующей команды, и наконец, остановы могут происходить в любой момент и вообще не предусматривать средств возврата управления в программу.
Команда INT (а также INTO и INT3) используется в программах как раз для того, чтобы вызывать обработчики прерываний (или исключений). Фактически они являются исключениями ловушки, поскольку адрес возврата, который передается обработчику, указывает на следующую команду, но так как эти команды были введены до разделения особых ситуаций на прерывания и исключения, их практически всегда называют командами вызова прерываний. Ввиду того, что обработчики прерываний и исключений в DOS обычно не различают механизм вызова, с помощью команды INT можно передавать управление как на обработчики прерываний, так и исключений.
Когда в реальном режиме выполняется команда INT, управление передается по адресу, который считывается из специального массива, таблицы векторов прерываний, начинающегося в памяти по адресу 0000h:0000h. Каждый элемент этого массива представляет собой дальний адрес обработчика прерывания в формате сегмент: смещение или 4 нулевых байта, если обработчик не установлен. Команда INT помещает в стек регистр флагов и дальний адрес возврата, поэтому, чтобы завершить обработчик, надо выполнить команды popf и retf или одну команду iret, которая в реальном режиме полностью им аналогична.
; Пример обработчика программного прерывания
int_handler proc far
push 0; сегментный адрес таблицы
pushf; поместить регистр флагов в стек
cli; запретить прерывания
; (чтобы не произошло аппаратного прерывания между следующими
; командами, обработчик которого теоретически может вызвать INT 87h
; в тот момент, когда смещение уже будет записано, а сегментный
; адрес еще нет, что приведет к передаче управления
; в неопределенную область памяти)
; поместить дальний адрес обработчика int_handler в таблицу
; векторов прерываний, в элемент номер 87h (одно из неиспользуемых прерываний)
mov word ptr es: [87h*4], offset int_handler
mov word ptr es: [87h*4+2], seg int_handler
popf; восстановить исходное значение флага IF
Теперь команда INT 87h будет вызывать наш обработчик, то есть приводить к записи 0 в регистр АХ.
; скопировать адрес предыдущего обработчика в переменную old_handler
mov eax, dword ptr es: [87h*4]
mov dword ptr old_handler, eax
; установить наш обработчик
mov word ptr es: [87h*4], offset int_handler
mov word ptr es: [87h*4+2], seg int_handler
; восстановить предыдущий обработчик
mov eax, word ptr old_handler
mov word ptr es: [87h*4], eax
; скопировать адрес предыдущего обработчика в переменную old_handler
mov ax, 3587h; АН = 35h, AL = номер прерывания
int 21h; функция DOS: считать
; адрес обработчика прерывания
mov word ptr old_handler, bx; возвратить
mov word ptr old_handler+2, es; и сегментный
; установить наш обработчик
mov ax, 2587h; АН = 25h, AL = номер прерывания
mov dx, seg int_handler; сегментный адрес
mov dx, offset int_handler; смещение в DX
int 21h; функция DOS: установить
; (не забывайте, что ES изменился после вызова функции 35h!)
; восстановить предыдущий обработчик
lds dx, old_handler; сегментный адрес в DS и смещение в DX
mov ax, 2587h; АН = 25h, AL = номер прерывания
int 21h; установить обработчик
Обычно обработчики прерываний используют для того, чтобы обрабатывать прерывания от внешних устройств или чтобы обслуживать запросы других программ. Эти возможности рассмотрены далее, а здесь показано, как можно использовать обычный обработчик прерывания (или, в данном случае, исключения ошибки) для того, чтобы быстро найти минимум и максимум в большом массиве данных.
; находит минимальное и максимальное значения в массиве слов
; Ввод: DS:BX = адрес начала массива
; СХ = число элементов в массиве
; АХ = максимальный элемент
ВХ = минимальный элемент
; установить наш обработчик прерывания 5
mov еах, dword ptr es: [5*4]
mov dword ptr old_int5, eax
mov word ptr es: [5*4], offset int5_handler
mov word ptr es: [5*4]+2, cs
; инициализировать минимум и максимум первым элементом массива
mov ax, word ptr [bx]
mov word ptr lower_bound, ax
mov word ptr upper_bound, ax
mov di, 2; начать со второго элемента
mov ax, word ptr [bx] [di]; считать элемент в АХ
bound ax, bounds; команда BOUND вызывает
; если АХ не находится в пределах lower_bound/upper_bound
add di, 2; следующий элемент
loop bcheck; цикл на все элементы
; восстановить предыдущий обработчик
mov eax, dword ptr old_int5
mov dword ptr es: [5*4], eax
mov ax, word ptr upper_bound
mov bx, word ptr lower_bound
; обработчик IT 5 для процедуры minmax
; сравнить АХ со значениями upper_bound и lower_bound и копировать
; AX в один из них, обработчик не обрабатывает конфликт между
; исключением BOUND и программным прерыванием распечатки экрана INT 5.
; Нажатие клавиши PrtScr в момент работы процедуры minmax приведет
; к ошибке. Чтобы это исправить, можно, например, проверять байт,
; на который указывает адрес возврата, если это CDh
; (код команды INT), то обработчик был вызван как INT 5
int5_handler proc far
cmp ax, word ptr lower_bound; сравнить АХ с нижней границей,
; это было нарушение
mov word ptr upper_bound, ax; верхней границы
mov word ptr lower_bound, ax; если это было нарушение
iret; нижней границы
Рассмотрим их кратко в порядке убывания приоритетов (прерывание имеет более высокий приоритет, и это означает, что, пока не завершился его обработчик, прерывания с низкими приоритетами будут ждать своей очереди).
приводит к тому, что, когда старый обработчик выполнит команду IRET, управление сразу же перейдет к прерванной программе. Этот способ применяют, если нужно, чтобы сначала отработал новый обработчик, а потом он передал бы управление старому.
Посмотрим, как работает перехват прерывания от таймера на следующем примере:
; демонстрация перехвата прерывания системного таймера: вывод текущего времени
; в левом углу экрана
186; для pusha/popa и сдвигов
; сохранить адрес предыдущего обработчика прерывания 1Ch
mov ax, 351Ch; АН = 35h, AL = номер прерывания
int 21h; функция DOS: определить адрес обработчика
mov word ptr old_int1Ch, bx; прерывания
mov word ptr old_int1Ch+2, es; (возвращается в ES:BX)
; установить наш обработчик
mov ax, 251Ch; АН = 25h, AL = номер прерывания
int 21h; установить обработчик прерывания 1Ch
; здесь размещается собственно программа, например вызов command.com
int 21h; ожидание нажатия на любую клавишу
; восстановить предыдущий обработчик прерывания 1Ch
mov ax, 251Ch; АН = 25h, AL = номер прерывания
mov dx, word ptr old_int1Ch+2
old_int1Ch dd?; здесь хранится адрес предыдущего обработчика
start_position dw 0; позиция на экране, в которую выводится текущее время
; обработчик для прерывания 1Ch
; выводит текущее время в позицию start_position на экране
; (только в текстовом режиме)
int1Ch_handler proc far
pusha; обработчик аппаратного прерывания
push es; должен сохранять ВСЕ регистры
push cs; на входе в обработчик известно только
pop ds; значение регистра CS
mov ah, 02h; Функция 02h прерывания 1Ah:
int 1Ah; чтение времени из RTC,
; AL = час в BCD-формате
call bcd2asc; преобразовать в ASCII,
mov byte ptr output_line[2], ah; поместить их в
mov byte ptr output_line[4], al; строку output_line
mov al, cl; CL = минута в BCD-формате
mov byte ptr output_line[10], ah
mov byte ptr output_line[12], al
mov al, dh; DH = секунда в BCD-формате
mov byte ptr output_line[16], ah
mov byte ptr output_line[18], al
pop es; адрес в видеопамяти
mov di, word ptr start_position; в ES:DI
mov si, offset output_line; адрес строки в DS:SI
rep movsb; скопировать строку
pop ds; восстановить все регистры
jmp cs:old_int1Ch; передать управление предыдущему обработчику
; преобразует старшую цифру упакованного BCD-числа из AL в ASCII-символ,
and al, 0Fh; оставить младшие 4 бита в AL
shr ah, 4; сдвинуть старшие 4 бита в АН
or ах, 3030h; преобразовать в ASCII-символы
; строка «00h 00:00» с атрибутом 1Fh (белый на синем) после каждого символа
output_line db ‘ ‘, 1Fh, ‘0’, 1Fh, ‘0’, 1Fh, ‘h’, 1Fh
db ‘ ‘, 1Fh, ‘0’, 1Fh, ‘0’, 1Fh, ‘:’, 1Fh
db ‘0’, 1Fh, ‘0’, 1Fh, ‘ ‘, 1Fh
Разумеется, обработка прерываний не должна занимать много времени: если прерывание происходит достаточно часто (например, прерывание последовательного порта может происходить 28 800 раз в секунду), его обработчик обязательно должен выполняться за более короткое время. Если, например, обработчик прерывания таймера будет выполняться 1/32,4 секунды, то есть половину времени между прерываниями, вся система будет работать в два раза медленнее. А если еще одна программа с таким же долгим обработчиком перехватит это прерывание, система остановится совсем. Именно поэтому обработчики прерываний принято писать исключительно на ассемблере.
Пусть у нас есть собственный обработчик программного прерывания, который вызывают обработчики двух аппаратных прерываний, и пусть эти аппаратные прерывания произошли сразу одно за другим. В этом случае может получиться так, что второе аппаратное прерывание осуществится в тот момент, когда еще не закончится выполнение нашего программного обработчика. В большинстве случаев это не приведет ни к каким проблемам, но, если обработчик обращается к каким-либо переменным в памяти, могут произойти редкие, невоспроизводимые сбои в его работе. Например, пусть в обработчике есть некоторая переменная counter, используемая как счетчик, считающий от 0 до 99:
mov al, byte ptr counter; считать счетчик в AL,
cmp al, 100; проверить его на переполнение,