Прерывания INT 25h и INT 26h — КиберПедия 

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Прерывания INT 25h и INT 26h

2020-12-06 235
Прерывания INT 25h и INT 26h 0.00 из 5.00 0 оценок
Заказать работу

Для работы с логическим диском (или дискетой) на уровне логических номеров секторов MS-DOS предоставляет программам два прерывания - INT 25h (чтение сектора по его логическому номеру) и INT 26h (запись сектора по его логическому номеру). Вызов этих прерываний имеет различный формат для разных версий MS-DOS. Для тех версий, которые не поддерживают размер логических дисков более 32 Мбайт (MS-DOS 3.10, 3.20, 3.30) используется следующий формат:

  • INT 25h - Чтение сектора по его логическому номеру
На входе: AL Адрес НГМД или НМД (0 - A:, 1 - B:,...)
  CX Количество секторов, которые нужно прочитать
  DX Логический номер начального сектора
  DS:BX Адрес буфера для чтения
На выходе: AH Код ошибки при неуспешном завершении операции
  CF 1, если произошла ошибка, 0, если ошибки нет
  • INT 26h - Запись сектора по его логическому номеру
На входе: AL Адрес НГМД или НМД (0 - A:, 1 - B:,...)
  CX Количество секторов, которые нужно записать
  DX Логический номер начального сектора
  DS:BX Адрес буфера, содержащего данные
На выходе: AH Код ошибки при неуспешном завершении операции
  CF 1, если произошла ошибка, 0, если ошибки нет

Для более поздних версий MS-DOS и для COMPAQ DOS версии 3.31 используется другой способ указания номера логического сектора.

Так как шестнадцати разрядов недостаточно для адресации диска размером более 32 Мбайт, то при работе с расширенным разделом диска, занимающим более 32 Мбайт, регистры используются по-другому.

Регистр CX содержит FFFFh - признак того, что программа работает с логическим диском, имеющим размер более 32 Мбайт.

Регистры DS:BX содержат адрес следующей структуры:

Смещение Размер Содержимое
0 4 Начальный номер логического сектора
4 2 Количество секторов для чтения или записи
6 4 Дальний адрес буфера для передачи данных

Так как для указания начального номера логического сектора в этом управляющем блоке отводится 4 байта, то снимается указанное ранее ограничение на размер логического диска.

Сделаем очень важное замечание, касающееся только что рассмотренных прерываний MS-DOS.

Эти прерывания оставляют в стеке одно слово - старое значение регистра флагов. Поэтому после вызова прерывания должна следовать, например, такая команда: pop ax

Содержимое загрузочного сектора может быть использовано для определения общего количества секторов на логическом диске, для работы с таблицей размещения файлов FAT, для определения других характеристик логического диска.


Пояснительная записка к программе 1 (способ 1)

Для работы с загрузочной записью используются структуры EBPB и BOOT, описывающие расширенный блок параметров и загрузочную запись, соответственно.

Поле серийного номера диска разбито на две компоненты - volser_lo и volser_hi. Это сделано для облегчения представления серийного номера в том виде, который используется командой DIR операционной системы MS-DOS.

Программа содержит комментарии, поясняющие ход выполнения операторов, обоснованных вышеизложенным теоретическим материалом. 

 
Задача 1.

Условие:

Найти серийный номер диска.

Способ 2: программа помещает загрузочную запись в некоторую область памяти длины 512 байт и, увеличив адрес её начала на нужную величину, непосредственно получает требуемый результат.


Листинг программы:

 

/* Текст программы и выходные результаты  */

#include <stdio.h>

#include <alloc.h>

#include <dos.h>

/* Функция getbootc() считывает загрузочную запись

указанного НМД непосредственно в область из 512 байтов,

возвращает 0 в случае успешного считывания, а иначе - 1 */

int getbootc(char *boot,int drive)

{ union REGS reg;

struct SREGS segreg;

/* Заполняем регистровые структуры для вызова

прерывания DOS int 25h */

reg.x.ax=drive; reg.x.bx=FP_OFF(boot);

segreg.ds=FP_SEG(boot); reg.x.cx=1; reg.x.dx=0;

int86x(0x25,&reg,&reg,&segreg); return(reg.x.cflag);

}

void main(void)

{

char far * boot_rc;

int statusc; char drive;

/* Заказываем буфер для чтения BOOT-записи */

/* Адрес буфера присваиваем far-указателю */

boot_rc=malloc(512); /* Такова длина сектора загрузочного */

/* Запрашиваем диск, для которого необходимо выполнить

чтение загрузочной записи                        */

printf("\nВведите обозначение диска (A, B,...): ");

drive=getche();

/* Вычисляем номер дисковода */

drive=toupper(drive)-'A';

/* Читаем загрузочную запись в буфер */

statusc=getbootc((char far *)boot_rc,drive);

/* Если произошла ошибка, то завершим работу */

if(statusc)

 

{ printf("\nОшибка при чтении BOOT-сектора\n"); exit(-1); }

printf("\nКоличество секторов на дорожке равно %04x-%04x\n",

*(char *)(boot_rc+39)); /* 11 байт до начала

        подстр-ры EBPB, а там ещё сдвиг 2 байт */

/* Освобождаем буфер */ free(boot_rc);

}


Пояснительная записка к программе 1 (способ 2).

 

Здесь приводится листинг решения задачи, в котором загрузочная запись считывается в область памяти длины 512 байт. При этом используется прерывание DOS INT 25h, которое читает сектор по его логическому номеру.

На входе этого прерывания в регистр AL заносится адрес НГМД или НМД (0 - A:, 1 - B:,...); в CX - количество секторов, которые нужно прочитать; в DX - логический номер начального сектора; в DS:BX - адрес буфера для чтения. На выходе прерывания INT 25h в регистр AH помещён код ошибки при неуспешном завершении операции, а флаг CF содержит 1, если произошла ошибка и 0, если ошибки нет. Поскольку в рассматриваемом прерывании значения задаются и в сегментном регистре, то для реализации прерывания используется функция int86x, прототип которой описан в dos.h и имеет вид 

int int86x(int intno, union REGS *inregs, union REGS *outregs,

struct SREGS *segregs)

 

Шаблон структуры SREGS содержится в файле dos.h и имеет вид

struct SREGS {

           unsigned int es;

           unsigned int cs;

           unsigned int ss;

           unsigned int ds;

};

По выходу из прерывания в переменную segreg копируются значения всех сегментных регистров. В функции getbootc() указано, как заполняются регистровые структуры для вызова прерывания 25h. В результате вызова функции getbootc() в буфер, выделенный функцией malloc(), считывается загрузочная запись указанного НМД.

Адрес буфера присваивается far-указателю boot_rc.

Далее, чтобы ответить на вопрос задачи, т.е. определить количество секторов на одну копию FAT, следует воспользоваться форматом загрузочной. Искомая величина находится в блоке параметров BIOS (BPB) со смещением 11 байт от его начала, а сам блок параметров BIOS располагается со смещением 11 байт от начала загрузочного сектора.

Поэтому количество секторов на одну копию FAT определяется величиной *(unsigned *)(boot_rc+22). Здесь операция приведения типа (unsigned *) сообщает компилятору размер объекта.

Использованное прерывание int 25h, а также BOOT-сектор имеют различный формат для разных версий MS-DOS. Выше использован формат для тех версий, которые не поддерживают размер логических дисков более 32 Мбайт.


Задача 2.

Условие:

Записать в буфер клавиатуры последовательность символов согласно выбранному варианту тремя способами (три программы на языке Си): с использованием функции 5 прерывания 16h, осуществляя непосредственный доступ к ячейкам памяти, выделенным под буфер клавиатуры, по текущему значению указателя "головы" буфера; то же, но по текущему указателю "хвоста" буфера.

 

Сменить активность окон программной оболочки Нортон, поместив в буфер клавиатуры код клавиши <Tab>.

 

 

Способ 1:

С использованием функции 5 прерывания 16h


Листинг программы:

 

#include <io.h>

#include <dos.h>

#include <process.h>

#include <conio.h>

#include <stdio.h>

#include <fcntl.h>

#include <sys\types.h>

#include <sys\stat.h>

#include <errno.h>

 

main()

{

union REGS rg;

int i;

 

rg.h.ah = 5;

rg.h.cl = 0x09;

rg.h.ch = 0x0F;

int86(0x16, &rg, &rg);

 

system("c:\\nc\\nc.exe");

return 0;

 

}


Пояснительная записка к задаче 2 (способ 1):

 

Набор функций для работы с клавиатурой, предоставляемый в распоряжение программиста прерыванием BIOS INT 16h, включает в себя функции для выборки кода нажатого символа из буфера с ожиданием нажатия, функции для проверки содержимого буфера и для управления содержимым буфера, функции для изменения скоростных характеристик клавиатуры.

 

С помощью функции 05h (прерывание 16h) можно вставить символы в буфер клавиатуры, как-будто они были введены оператором.

 

Регистры на входе: AH = 05h; CL = код ASCII записываемого символа; CH = скан-код записываемого символа, или 0
Регистры на выходе: AL = 0 - запись выполнена успешно; AL = 1 - буфер клавиатуры переполнен

 

Приведенная ниже фрагмент программы используется выше, для описания вводимых в память клавиатуры символов, на примере записи в буфер клавиатуры пять символов '*'. Если запустить программу, содержащую этот фрагмент кода, а затем посмотреть на системное приглашение, то вы увидите что-нибудь похожее на C:\>*****.

union REGS rg;

int i;

for(i=0; i<5; i++)

{

rg.h.ah = 5;

rg.h.cl = '*';

rg.h.ch = 9;

int86(0x16, &rg, &rg);

}

Для определения скан-кодов и кодов ASCII нажимаемых клавиш использовалась следующая программа:

 

#include <stdio.h>

#include <dos.h>

 

int main(void)

{

union REGS rg;

 

printf("Press <ESC> to exit\n");

 

for(;;)

{

// Вызываем прерывание INT 16h

rg.h.ah = 0;

int86(0x16, &rg, &rg);

 

// Выводим на экран содержимое регистров AH и AL,

// содержащих, соответственно, скан-код и код ASCII

// нажатой клавиши

printf("\nScan = %02.2X Ascii = %02.2X",

rg.h.ah, rg.h.al);

 

// Если была нажата клавиша ESC, завершаем работу

// программы

if(rg.h.ah == 1)

break;

}

return 0;

}

 

Буфер клавиатуры

Буфер клавиатуры имеет длину 32 байта и расположен в компьютере IBM PC/XT по адресу 0000h:041Eh.

В компьютерах моделей IBM PC/AT и IBM PS/2 расположение клавиатурного буфера задается содержимым двух слов памяти с адресами 0000h:0480h (смещение адреса начала буфера) и 0000h:0482h (смещение конца буфера). Обычно эти ячейки памяти содержат значения, соответственно, 001Eh и 003Eh. Так как смещения заданы относительно сегментного адреса 0040h, то стандартное расположение клавиатурного буфера в IBM PC/AT и IBM PS/2 соответствует его расположению в IBM PC/XT.

Буфер клавиатуры организован циклически. Это означает, что при его переполнении самые старые значения будут потеряны. Две ячейки памяти, находящиеся в области данных BIOS с адресами 0000h:041Ah и 0000h:041Ch содержат, соответственно, указатели на начало и конец буфера. Если значения этих указателей равны друг другу, буфер пуст.

Заметим, что вы можете удалить все символы из буфера клавиатуры, установив оба указателя на начало буфера. Однако есть более предпочтительный способ с использованием прерывания BIOS INT 16h, функции которого мы опишем позже в этой главе.

Указателями на начало и конец клавиатурного буфера обычно управляют обработчики прерываний INT 09h и INT 16h. Программа извлекает из буфера коды нажатых клавиш, используя различные функции прерывания INT 16h.

При переполнении внутреннего буфера клавиатуры или буфера, расположенного в области данных BIOS программа-обработчик прерывания INT 09h генерирует звуковой сигнал.

В программах MS-DOS у вас едва ли появится необходимость непосредственного манипулирования содержимым буфера клавиатуры - вы можете использовать прерывание BIOS INT 16h для выполнения практически всех клавиатурных операций.


Способ 2: по текущему значению указателя "головы" буфера

Способ 3: по текущему значению указателя "хвоста"  буфера

 

Листинги программ:

#include <io.h>

#include <dos.h>

#include <process.h>

#include <conio.h>

#include <stdio.h>

#include <fcntl.h>

#include <sys\types.h>

#include <sys\stat.h>

#include <errno.h>

#define KB_BUFFER_START 0x1e /* Смещение начала буфеpа клавиатуpы */

#define KB_BUFFER_END 0x3e /* Смещение конца буфеpа клавиатуpы */

#define HEAD_PTR   0x1a /* Смещение указателя "головы" */

#define TAIL_PTR   0x1c /* Смещение указателя "хвоста" */

#define OK  0 /* Код нажатия записан в буфеp */

#define FULL 1 /* Буфеp клавиатуpы заполнен до пpедела */

/* Записать один символ в буфер клав-ры с "хвоста" */

int enter_kbt(unsigned key_code)

{unsigned register _es *head=(unsigned _es *) HEAD_PTR,

       _es *tail=(unsigned _es *) TAIL_PTR,

               _es *tmp,ret;

_ES=0x40;

disable(); /* Начало кpитической секции кода */

tmp=(unsigned _es *) *head;

if(tmp==(unsigned _es *)KB_BUFFER_START)

/* "Пеpескок" указателя на конец буфеpа */

tmp=(unsigned _es *)KB_BUFFER_END;

if(tmp-1==(unsigned _es *)*tail) /* Буфеp полон */

ret=FULL;

else

{ *(unsigned _es *)tmp=key_code;

tmp--;

*head=(unsigned)tmp;

    ret=OK; }

enable(); return ret;

}

 

int main()

{

unsigned key_codes[]={0x0f09};

/* В массиве key_codes[]все перечисленой в первом варианте*/

FILE *iii;

int source, taget, i;

char *buffer;

int count;

/*system("c:\\nc\\nc.exe");*/

  while(kbhit()) getch(); /* Очистка буфеpа клавиатуpы */

/* Запись в буфеp клавиатуpы массива key_codes с "головы". */

for(i=0;i>-1;i--)

{

enter_kbt(key_codes[i]);

}

system("c:\\nc\\nc.exe");

 }

 

 


#include <io.h>

#include <dos.h>

#include <process.h>

#include <conio.h>

#include <stdio.h>

#include <fcntl.h>

#include <sys\types.h>

#include <sys\stat.h>

#include <errno.h>

#define KB_BUFFER_START 0x1e /* Смещение начала буфеpа клавиатуpы */

#define KB_BUFFER_END 0x3e /* Смещение конца буфеpа клавиатуpы */

#define HEAD_PTR   0x1a /* Смещение указателя "головы" */

#define TAIL_PTR   0x1c /* Смещение указателя "хвоста" */

#define OK  0 /* Код нажатия записан в буфеp */

#define FULL 1 /* Буфеp клавиатуpы заполнен до пpедела */

/* Записать один символ в буфер клав-ры с "хвоста" */

int enter_kbt(unsigned key_code)

{unsigned register _es *tail=(unsigned _es *) TAIL_PTR,

               _es *head=(unsigned _es *) HEAD_PTR,

               _es *tmp,ret;

_ES=0x40;

disable(); /* Начало кpитической секции кода */

tmp=(unsigned _es *) *tail;

if(tmp==(unsigned _es *)KB_BUFFER_END)

/* "Пеpескок" указателя на начало буфеpа */

tmp=(unsigned _es *)KB_BUFFER_START;

if(tmp+1==(unsigned _es *)*head) /* Буфеp полон */

ret=FULL;

else

{ *(unsigned _es *)tmp=key_code;

   tmp++;

   *tail=(unsigned)tmp;

    ret=OK; }

enable(); return ret;

}

 

int main()

{

unsigned key_codes[]={0x0f09};

/* В массиве key_codes[]все перечисленой в первом варианте*/

FILE *iii;

int source, taget, i;

char *buffer;

int count;

/*system("c:\\nc\\nc.exe");*/

  while(kbhit()) getch(); /* Очистка буфеpа клавиатуpы */

/* Запись в буфеp клавиатуpы массива key_codes с "хвоста". */

for(i=0;i<1;i++)

{

enter_kbt(key_codes[i]);

}

system("c:\\nc\\nc.exe");

 }

 


Пояснительная записка к задаче 2 (способы 2 и3):

 

Буфер клавиатуры организуется, как кольцевая очередь, доступ к которой осуществляется с помощью указателя "головы": (head pointer), адрес которого 40h:1Ah, и указателя "хвоста" с адресом 40h:1Ch.  Указатель "хвоста" задаёт смещение, где будет записан обработчиком прерывания 9 двухбайтовый код буферизуемой клавиши. Указатель "головы" задаёт смещение возвращаемого слова по запросу операционной системы или BIOSа. Буфер клавиатуры занимает 32 байта памяти с адреса 40h:1Eh до 40h:3Eh. Если значения указателей "головы" и "хвоста" равны между собой, то буфер пуст.

В приведенном листинге функция int enter_kbt(unsigned key_code) вводит в первом случае с «головы», во втором с «хвоста» в буфер клавиатуры символ key_code.

Используются переменные tail, head, tmp типа register unsigned _es *. tail - это адрес, по которому хранится адрес "хвоста"; head - адрес, содержащий адрес "головы"; tmp - значение * tail указателя "хвоста" в способе 3 и значение * head указателя «головы» в способе 2, преобразованное к виду (unsigned _es *). В случае, когда tmp указывает на конец буфера, то ему присваивается значение на начало буфера и наоборот. Поэтому значение указателя "хвоста" может быть и меньше значения указателя "головы" и наоборот.

Если (для способа 3) tmp+1=(unsigned _es *)*head, то буфер полон и происходит выход из функции.

Если (для способа 2) tmp-1=(unsigned _es *)* tail, то буфер полон и происходит выход из функции.


Задача 3.

Условие:

Составить и отладить резидентную программу, которая, используя обработчики прерываний 9 и 1Ch, позволяет по нажатию определённой переключательной клавиши вызвать на экране появление заданного слова.

Создать резидентную программу, которая выводит на терминал слово "scanf" по нажатию ScrollLock.


Листинг программы:

 

#include <stdio.h>

#include <dos.h>

#define TAIL_PTR 0x1c

#define HEAD_PTR 0x1a

#define SOST_KLAV 0x18

void interrupt (*old_int09)(); /* Для стандартного обработчика

          прерывания 9 (нажатие/отпускание клавиши) */

void interrupt (*old_int1c)(); /* Для стандартного обработчика

          прерывания 0x1c (от таймера) */

 

union REGS rg;

int active,i; char c;

int n1,n2,n3,j,zflag;

unsigned key_codes[]={0x2267,0x1265,0x1474,0x2e63,0x2368,0x1e61,0x1372};

/* В массиве key_codes[] слово "skanf" в виде скэн-ASCII-кодов.

Но, если вместо скэн-составляющих здесь указать просто 6 нулей

или 6 любых скэн-кодов, то ничего от этого не изменится. */

void interrupt new_int1c()

{ /* Новый обработчик прерывания 0x1c - (от таймера) */

if(active)

{ i++; if(i>7) active=0;

else

{ disable();

  rg.x.ax=0x0500; /* Номеp вызываемой

  функции для пpеpывания 16h pавен ah=05h */

  rg.x.cx=key_codes[i]; /* ch - скэн-код, а cl - ASCII-код

  символа,записываемого в буфеp клавиатуpы */

  int86(0x16,&rg,&rg); /* тепеpь в al будет 0 если и только

  если запись в буфеp удалась, т.е. он не пеpеполнен */

  enable(); }

}

(*old_int1c)(); /* Передадим управление старому

обработчику прерывания 0x1c */

}

void interrupt new_int09()

{ /* Новый обработчик прерывания 0x09 -

(нажатие/отпускание любой клавиши)      */

register unsigned _es *t1, _ec *t2, _ec *t3;

disable();

t1=SOST_KLAV&0x40;

t2=TAIL_PTR&0x40;

t3=HEAD_PTR&0x40;

n2=*t2; n3=*t3; n1=*t1;

printf("n1 = %x",n1&0x10);

if(((n1&0x10)==0x36)&&(!active)&&(n2==n3))

/* Если прижата RightShift и active==0 и буфер клавиатуры пуст*/

{ i=-1; active=1;j=0;

for(j=0;j<6;j++)

printf("%c",key_codes[j]); (*old_int09)();}

else

(*old_int09)();

/* Передадим управление старому обработчику прерывания 0x09 */

enable();

}

 

void main(void)

{ /* Прототипы вызываемых отсюда ф-ий - в dos.h */

active=0; disable(); /* Запретить прерывания */

old_int09=getvect(0x09); /* Запомнит старый вектор 9-го

прер-ия (нажатие или отпускание клавиши) */

setvect(0x09,new_int09); /* Занести на место этого вектора

          новый - адрес нашего обработчика */

old_int1c=getvect(0x1c); /* Запомнит старый вектор

прер-ия 0x1c (от таймера) */

setvect(0x1c,new_int1c); /* Занести на место вектора 0x1c

прер-ния от таймера - адрес нашего обработчика этого прер-ния */

enable(); /* Разрешить прерывания */

keep(0,750); /* Примерно разделили на 8 размер EXE-файла этой

программы и получили 750 */

}


Пояснительная записка к программе 3.

Составление собственных программ обработки прерываний и замена стандартных обработчиков MS-DOS и BIOS является достаточно сложной задачей. Необходимо учитывать все тонкости работы аппаратуры, а также взаимодействия программного и аппаратного обеспечения. При отладке возможно разрушение операционной системы с непредсказуемыми последствиями, поэтому надо очень внимательно следить за тем, что делает ваша программа.

Таблица векторов прерываний

Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти. Эта таблица находится в диапазоне адресов от 0000:0000 до 0000:03FFh и состоит из 256 элементов - дальних адресов обработчиков прерываний.

Элементы таблицы векторов прерываний называются векторами прерываний. В первом слове элемента таблицы записана компонента смещения, а во втором - сегментная компонента адреса обработчика прерывания.

Вектор прерывания с номером 0 находится по адресу 0000:0000, с номером 1 - по адресу 0000:0004 и т. д.

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

void (far* interrupt_table[256])();

Инициализация таблицы выполняется частично системой базового ввода/вывода BIOS после тестирования аппаратуры и перед началом загрузки операционной системой, частично при загрузке MS-DOS. Операционная система MS-DOS может изменить некоторые вектора прерываний, установленные BIOS.

Расскажем о назначении наиболее важных векторов прерываний.

Номер Описание
0 Ошибка деления.Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). Обычно при обработке этого прерывания MS-DOS выводит сообщение об ошибке и останавливает выполнение программы. При этом для процессора i8086 адрес возврата указывает на команду, следующую после команды деления, а для процессора i80286 и более старших моделей - на первый байт команды, вызвавшей прерывание
1 Прерывание пошагового режима.Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после пересылки данных в сегментные регистры командами MOV и POP
2 Аппаратное немаскируемое прерывание.Это прерывание может использоваться по-разному в разных машинах. Обычно оно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора
3 Прерывание для трассировки. Генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания
4 Переполнение. Генерируется машинной командой INTO, если установлен флаг переполнения OF. Если флаг не установлен, команда INTO выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций
5 Печать копии экрана. Генерируется, если пользователь нажал клавишу <PrtSc>. В программах MS-DOS обычно используется для печати образа экрана. Для процессора i80286 и более старших моделей генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона
6 Неопределенный код операции или длина команды больше 10 байт
7 Особый случай отсутствия арифметического сопроцессора
8 IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду
9 IRQ1 - прерывание от клавиатуры. Генерируется, когда пользователь нажимает и отжимает клавиши. Используется для чтения данных из клавиатуры
A IRQ2 - используется для каскадирования аппаратных прерываний
B IRQ3 - прерывание асинхронного порта COM2
C IRQ4 - прерывание асинхронного порта COM1
D IRQ5 - прерывание от контроллера жесткого диска (только для компьютеров IBM PC/XT)
E IRQ6 - прерывание генерируется контроллером НГМД после завершения операции ввода/вывода
F IRQ7 - прерывание от параллельного адаптера. Генерируется, когда подключенный к адаптеру принтер готов к выполнению очередной операции. Обычно не используется
10 Обслуживание видеоадаптера
11 Определение конфигурации устройств в системе
12 Определение размера оперативной памяти
13 Обслуживание дисковой системы
14 Работа с асинхронным последовательным адаптером
15 Расширенный сервис
16 Обслуживание клавиатуры
17 Обслуживание принтера
18 Запуск BASIC в ПЗУ, если он есть
19 Перезагрузка операционной системы
1A Обслуживание часов
1B Обработчик прерывания, возникающего, если пользователь нажал комбинацию клавиш <Ctrl+Break>
1C Программное прерывание, вызывается 18,2 раза в секунду обработчиком аппаратного прерывания таймера
1D Адрес видеотаблицы для контроллера видеоадаптера 6845
1E Указатель на таблицу параметров дискеты
1F Указатель на графическую таблицу для символов с кодами ASCII 128-255
20-5F Используется MS-DOS или зарезервировано для MS-DOS
60-67 Прерывания, зарезервированные для программ пользователя
68-6F Не используются
70 IRQ8 - прерывание от часов реального времени
71 IRQ9 - прерывание от контроллера EGA
72 IRQ10 - зарезервировано
73 IRQ11 - зарезервировано
74 IRQ12 - зарезервировано
75 IRQ13 - прерывание от арифметического сопроцессора
76 IRQ14 - прерывание от контроллера жесткого диска
77 IRQ15 - зарезервировано
78 - 7F Не используются
80-85 Зарезервировано для BASIC
86-F0 Используются интерпретатором BASIC
F1-FF Не используются

Прерывания, обозначенные как IRQ0 - IRQ15 являются аппаратными прерываниями.

 

Что это такое резидентная программа?

Обычно после завершения очередной программы MS-DOS освобождает место в памяти, которое занимала программа, чтобы загрузить на это место новую. Однако есть способ оставить программу в памяти и после ее завершения. Такая программа и будет резидентной, т. е. постоянно присутствующей в памяти.

Для чего используются резидентные программы?

Резидентные программы могут переключать на себя обработку прерываний, например, связанных с выводом на печать или с обращением к клавиатуре и т. д.

Вы можете встретить множество резидентных программ, предназначенных для загрузки русских шрифтов в память видеоконтроллера, для печати текста, содержащего символы кириллицы, на принтере в графическом режиме, для русификации клавиатуры и т. п. Все эти программы обычно запускаются один раз при загрузке компьютера через файл autoexec.bat.

Другой пример использования резидентных программ: резидентные калькуляторы, справочные базы данных или интегрированные системы, наподобие Borland SideKick.

Такие программы тоже обычно запускаются через файл autoexec.bat или при необходимости. Они перехватывают прерывания, предназначенные для работы с клавиатурой. Как только пользователь нажимает заранее определенную комбинацию клавиш, резидентная программа активизируется. Поверх имеющегося на экране изображения выводится диалоговое окно резидентной программы.

Иногда резидентные программы используют вместо загружаемых драйверов для обслуживания нестандартной аппаратуры. В этом случае резидентная программа может встроить свой обработчик, через который все прикладные программы смогут обращаются к аппаратуре.


Поделиться с друзьями:

Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.168 с.