Ввод-вывод данных по прерыванию
Наиболее часто прерывание используется для организации обмена данными с относительно медленными устройствами, чтобы программа " не теряла зря времени" при ожидании готовности устройства к вводу-выводу очередной порции информации. В таком случае возникает уже физический параллелизм между выполняемой программой и операцией ввода-вывода, производимой устройством. В качестве примера рассмотрим, как выглядит процесс посимвольного вывода по прерыванию строки в гипотетическое устройство последовательной передачи. Взаимодействие основной программы и обработчика прерываний также осуществляется через программное прерывание.
#define USERVEC 0x60 // Номер вектора
// программного прерывания
#define IOVEC ... // Номер вектора прерывания
// устройства
int cnt; // Текущая длина строки
char far *p=NULL; // Указатель на строку
// в основной программе
// NULL - устройство свободно
void interrupt
USERINT(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flgs)
// ds:dx - начальный адрес буфера,
// cx - размер буфера в байтах
// Программное прерывание запускает процесс вывода
// строки из буфера посимвольно по прерыванию
{
if (p!=NULL) {ax=0; return; } // Устройство занято
p = MK_FP(ds,dx); // Сформировать длинный
// указатель из регистров ds,dx
cnt=cx;
setvect(INT,IOVEC); // Установить вектор прерывания
// Разрешить прерывание от устройства
// в контроллере прерываний
// по соответствующему IRQ
// и в контроллере устройства ...
ax=1; // Выйти из программного прерывания
} // с _AX=1
void interrupt INT(...) // Прерывание от устройства по
{ char *c; // готовности к выводу символа
if (cnt==0) // Вывод закончен
{ p=NULL;
// Запретить прерывание от устройства в контроллере
// прерываний по соответствующему IRQ
// и в контроллере устройства ...
}
else
{ c=*p++;
cnt--; // Получить очередной байт и вывести
outportb(c,...);
}}