CodeNet / Платформы / Пишем ОС / Пишем "многозадачную" ОС в "Real Mode"
Перхватываем прерывание 08h.
Перопределения прерывания в MS DOS
Перехватить прерывание не есть проблема, основная проблема состоит в написании нового обработчика.
В MS DOS переопределение стандартного прерывания производится следующим образом:
- Получить адрес старого обработчика.
- Установить новый обработчик.
- Выполнить программу.
- восстановить старый обработчик.
Получаем адрес старого обработчика.
Таблица векторов прерывания находися с адреса 0000:0000 и имеет 256 элементов (по количеству прерываний). Каждый элемент таблицы - 4-ех байтный вектор - адресс процедуры обработчика.
Для получения адреса старого прерывания можно воспользоватся функцией 35h MS DOS: Дать вектор прерывания.
- Вход
- AH = 35h
- AL = номер прерывания (00h до 0FFh)
- Выход
- ES:BX = адрес обработчика прерывания
Описание:Возвращает значение вектора прерывания для INT (AL); то есть, загружает в BX 0000:[AL*4], а в ES - 0000:[(AL*4)+2].
mov ah,035h
mov al,008h
int 021h
mov [cs:oldseg08],es
mov [cs:oldofs08],bx
При отсутствии MS-DOS (мы в конце концов ОС пишем) можно на прямую прочитать значения таблицы векторов прерываний:
push ds
xor bx,bx
mov ds,bx
mov bx,[ds:0020h]
mov es,[ds:0022h]
mov [cs:oldseg08],es
mov [cs:oldofs08],bx
pop ds
Установаем новый обработчик.
Для установки адреса нового прерывания можно воспользоватся функцией 25h MS DOS: Установить вектор прерывания
- Вход
- AH = 25h
- AL = номер прерывания
- DS:DX = вектор прерывания: адрес программы обработки прерывания
- Выход
- нет
Устанавливает значение элемента таблицы векторов прерываний для прерывания с номером AL равным DS:DX.
Это равносильно записи 4-байтового адреса в 0000:(AL*4), но, в отличие от прямой записи, DOS здесь знает, что вы делаете, и гарантирует, что в момент записи прерывания будут заблокированы.
push ds
mov ax,cs
mov ds,ax
lea dx,[kernel] // Адрес нового обработчика
mov ah,025h
mov al,008h
int 021h
pop ds
При отсутствии MS-DOS можно на прямую изменить значения таблицы векторов прерываний:
call _di // Блокируем прерывания
push ds
xor bx,bx
mov ds,bx
lea bx,[cs:kernel] // Адрес нового обработчика
mov [ds:0020h],bx
mov [ds:0022h],cs
pop ds
call _ei // Разрешаем прерывания
Код отвечающий за установку новых прерываний находится в модуле mtasks.asm - процедуры getvectors, setvectors и restorevectors.