Операционная система MS-DOS — страница 10

  • Просмотров 5837
  • Скачиваний 439
  • Размер файла 27
    Кб

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

выходе из обработчика прерывания. void interrupt far int_funct(...) { // Тело обработчика прерывания } Ключевое слово interrupt используется также для описания переменных, предназначенных для хранения векторов прерываний: void interrupt (far *oldvect)(...); Для установки своего обработчика прерываний используется функция _dos_setvect. Эта функция имеет два параметра - номер прерывания и указатель на новую функцию обработки прерывания: _dos_setvect(0x16, my_key_intr); В этом примере

для прерывания номер 16h устанавливается новый обработчик прерывания my_key_intr. Для того чтобы узнать адрес старого обработчика прерывания по его номеру используется функция _dos_getvect, которая принимает в качестве параметра номер прерывания и возвращает указатель на соответствующий номеру обработчик: old_vector = _dos_getvector(0x16); Следующая программа иллюстрирует применение перечисленных выше функций для создания цепочки обработчиков

прерываний. Эта программа встраивает собственный обработчик прерываний от таймера, который будет вызываться 18,2 раза в секунду. Встраиваемый обработчик прерываний подсчитывает прерывания от таймера, и, если значение соответствующего счетчика кратно 20, громкоговоритель компьютера издает звуковой сигнал. В конце работы новый обработчик прерываний вызывает старый обработчик прерываний. После установки нового обработчика

прерывания таймера основная программа ждет, когда пользователь нажмет любую клавишу, затем она восстанавливает старое содержимое вектора прерывания. #include <stdio.h> #include <dos.h> #include <conio.h> void main(void); void interrupt far timer(...); void interrupt (far *oldvect)(...); // Переменная для подсчета прерываний таймера volatile long ticks; void main(void); { // Сбрасываем счетчик ticks = 0; // Запоминаем адрес старого обработчика прерываний oldvect = dos_getvect (0x1c): // Устанавливаем новый

обработчик прерываний dos_setvect (0x1c, timer); printf ("nТаймер установлен. Нажмите любую клавишу...n"); getch(); // Восстанавливаем старый обработчик прерываний dos_setvect (0x1c, oldvect); } void interrapt far timer (...) { // Увеличиваем счетчик прерываний таймера ticks++; // Если значение счетчика кратно 20, выдаем сигнал на громкоговоритель // компьютера if (ticks % 20) == 0 ) { asm mov bx,0 asm mov ax,0E07h asm int 10h } // Вызываем старый обработчик прерываний _chain_intr (oldvect); } Порядок выполнения работы