Информатика и технология программирования

         

Обработка программного прерывания


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


&#35include &#60dos.h&#62
&#35define USERVEC 0x60 // Вектор программного прерывания


void interrupt
USERINT(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flgs)
// ds:dx - начальный адрес буфера


// cx - размер буфера в байта


// ax,bx - координаты строки x,y


// Программное прерывание выводит строку из буфера


// непосредственно в видеопамять


{
char far *p; // Указатель на буфер строки


char (far *video)[25][80][2]; // Указатель на на страницу 0


video=0xB8000000; // видеопамяти


p = MK_FP(ds,dx); // Сформировать длинный


// указатель из регистров ds,dx




while(cx-- !=0) // bx,cx не сохраняются


{
(*video)[bx ][ax][0]= *p++;
(*video)[bx++][ax][1]= 0x5E;
}}


char name[80]="a-a-a-a-a-a-a-a";
void main()
{
union REGS R; // Union для установки содержимого


// регистров в программном прерывании


setvect(USERVEC, (void interrupt (far*)(...))USERINT);
// Установка вектора прерывания


R.x.ax=5; // Запись содержимого регистров


R.x.bx=10; // ax,bx - координаты строки


R.x.cx=strlen(name); // cx - длина строки


R.x.dx=name; // dx - начальный адрес строки


int86(USERVEC,&#38R,&#38R); // Выполнение программного


// прерывания по вектору USERVEC


_DX=name; // Альтернативный вариант


_CX=strlen(name); // с непосредственным


_BX=10; // использованием регистров


_AX=5;
geninterrupt(USERVEC);
}



Содержание раздела