Листинг 3. Текст программы PR_2.8 (окончание)
Выводы:
Данная программа заменяет стандартный обработчик прерывания int 0. При ее запуске на экран выдается надпись “'Warning: деление на ноль”. Вектор успешно сохраняется, о чем свидетельствует успешный запуск первой программы (инициирование деления на ноль).
При попадании в прерывание, в стек заносятся последовательно флаги, CS и IP. IP (instruction Pointer) указывает на месторасположение команды, вызвавшей прерывание. В нашем обработчике мы извлекаем это значение из стека и увеличиваем на 4. Затем снова заносим в стек и выходим из прерывания. Это сделано потому, что команда деления в данном случае занимает 4 байта, и если мы укажем значение меньше 4, то попадем в зону неопределенности для нас (в середину выполнения команды деления, например), но на вполне осознанную часть для процессора, который наверняка посчитает оставшиеся до 4 байты как коды команд и непременно их выполнит. По этой же причине опасно задавать значение, большее 4.
4. Модификация программы
Задание:
Преобразуйте вашу программу так, чтобы не применять функции DOS для получения и установки вектора прерываний int 0
print macro
push ax, dx
lea dx, #1
mov ah, 9
int 021
pop dx, ax
#em
jmp start
_error db 'Warning: деление на ноль', 13, 10, '$'
n_vect equ 0
old_v dd ?
start:
lea ax, new ;установка нового вектора
mov dx, cs ;сохранение старого
mov es, 0
es xchg w [n_vect*4], ax
es xchg w [n_vect*4+2], dx
mov w old_v, ax
mov w old_v + 2, dx
mov al, 11
mov bl, 0
div bl
mov ax, w old_v ;восстановление страрого вектора
mov dx, w old_v+2
es mov [n_vect*4], ax
es mov [n_vect*4+2], dx
int 020 ;выход
new:
print _error
pop ax
add ax, 2
push ax
iret
Листинг 4. Текст программы PR_3.8
Выводы:
Данная программа реализована без использования стандартных функций DOS для получения и установке вектора int 0. Как видно по обработчику прерывания, указатель смещается на 2 байта. И действительно, в этом случае команда деления занимает 2 байта.
В результате работы программы на экране по прежнему красуется гордая надпись “Warning: деление на ноль” что подтверждает корректности перехвата обработчика прерываний. Последующий запуск первой программы прошел успешно, обработчик перехватил прерывание и выдал соответствующее сообщение, что свидетельствует о корректном восстановлении вектора.
5. Передача управления обработчику BIOS
Задание:
Организуйте передачу управления обработчику BIOS после выполнения всех команд вашего прерывания, т.е. для выхода из Вашего обработчика используйте команду безусловного перехода по адресу системного обработчика.
print macro
push ax, dx
lea dx, #1
mov ah, 9
int 021
pop dx, ax
#em
jmp start
_error db 'Warning: деление на ноль', 13, 10, '$'
_msg db 'Все правильно))',13,10,'$'
n_vect equ 0
old_v dd ?
start:
mov ax, 035 by n_vect ;сохранение старого вектора
int 021 ;es:bx
mov w old_v, bx
mov w old_v + 2, es
mov ax, 025 by n_vect ;установка нового вектора
lea dx, new ;ds:dx
int 021
mov ax, 11
mov bl, 0
div bl
norm_exit:
mov ax, 025 by n_vect ;восстановление вектора
mov dx, w old_v ;ds:dx
mov ds, w old_v+2
int 021
mov ds, cs ;восстановление ds
print _msg
int 020 ;выход
new:
print _error
mov ax, 025 by n_vect
mov dx,w old_v
mov ds,w old_v+2
int 021
mov ds,cs
jmp old_v
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.