- •Отчёт о лабораторной работе №5
- •1. Стандартный обработчик int0
- •2. Замена стандартного обработчика int0 с использованием функций dos 25h и 35h
- •3. Замена стандартного обработчика int0 без использования функций dos 25h и 35h
- •4. Передача управления обработчику bios
- •5. Трассировка фрагмента программы
- •6. Сброс т-бита в обработчике int1
- •7. Использование вызовов прерываний по точке останова для ограничения трассируемого фрагмента программы
1. Стандартный обработчик int0
Чтобы проанализировать содержимое стандартного обработчика прерывания по ошибке операции деления, напишем программу, инициирующую это прерывание (файл p1-1.asm):
stacksg segment para stack 'Stack'
db 32 dup(?)
stacksg ends
codesg segment para 'Code'
begin proc far
assume ss:stacksg,cs:codesg
push ds ;помещаем в стек слово из ds
sub ax,ax ;и нулевое слово для корректного
push ax ;выхода из программы
mov ax,1234h
mov bl,0
div bl ;делим ax на bl
ret
begin endp
codesg ends
end begin
Ассемблируем, скомпонуем и запустим её:
C:\MASM611\BIN>ml p1-1.asm
Microsoft (R) Macro Assembler Version 6.11
Copyright (C) Microsoft Corp 1981-1993. All rights reserved.
Assembling: p1-1.asm
Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992
Copyright (C) Microsoft Corp 1984-1992. All rights reserved.
Object Modules [.obj]: p1-1.obj
Run File [p1-1.exe]: "p1-1.exe"
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:
C:\MASM611\BIN>p1-1.exe
Your program caused a divide overflow error.
If the problem persists, contact your program vendor.
2. Замена стандартного обработчика int0 с использованием функций dos 25h и 35h
Файл p1-2.asm:
stacksg segment para stack 'Stack'
dw 32 dup(?)
stacksg ends
datasg segment para 'Data'
stdOfs dw ?
stdSeg dw ?
mess db 'Произошло деление на ноль!',13,10,'$'
mess2 db 'Вышли из обработчика.',13,10,'$'
mess3 db 'Стандартный обработчик восстановлен. Проверка:',13,10,'$'
datasg ends
codesg segment para 'Code'
begin proc far
assume ss:stacksg,ds:datasg,cs:codesg
push ds ;помещаем в стек слово из ds
mov ax,0 ;и нулевое слово для корректного
push ax ;выхода из программы
mov ax,datasg ;запись datasg в ds
mov ds,ax ;для использования сегмента данных
;сохранение стандартного вектора прерывания
mov ah,35h ;получить вектор прерывания
mov al,0 ;номер прерывания
int 21h
mov stdOfs,bx ;сохранить смещение
mov stdSeg,es ;сохранить сегментный адрес
;задание собственного вектора
push ds
mov dx,offset myHandler
mov ax,seg myHandler
mov ds,ax
mov ah,25h
mov al,0
int 21h
pop ds
;инициация прерывания
divide: mov ax,1234h
mov bl,0
div bl ;делим ax на bl
mov dx,offset mess2
mov ah,9
int 21h
;восстановление стандартного вектора прерывания
push ds
mov dx,stdOfs
mov ax,stdSeg
mov ds,ax
mov ax,2500h
int 21h
pop ds
mov ah,9
mov dx,offset mess3
int 21h
jmp divide
ret
begin endp
myHandler proc
mov dx,offset mess
mov ah,9
int 21h
pop ax
inc ax
inc ax
push ax
iret
myHandler endp
codesg ends
end begin
Функция DOS 35h читает из AL номер прерывания и записывает адрес его обработчика из таблицы прерываний в ES:BX. Функция DOS 25h читает из DS:DX адрес обработчика прерывания и записывает его в строку таблицы прерываний, адрес которой указан в AL. Функция DOS 09h выводит на дисплей строку, начиная с адреса, указанного в DS:DX, до тех пор, пока не встретит символ '$'. При переходе на обработчик прерывания деления на ноль в стеке сохраняется адрес не следующей команды, а команды вызвавшей прерывание. Команда IRET извлекает из стека 3 слова и помещает их в IP, CS и регистр флагов. Поэтому в myHandler верхнее слово извлекается из стека, инкрементируется и кладется обратно. Результат:
C:\MASM611\BIN>p1-2.exe
Произошло деление на ноль!
Вышли из обработчика.
Стандартный обработчик восстановлен. Проверка:
Your program caused a divide overflow error.
If the problem persists, contact your program vendor.
В рекомендуемом алгоритме было предложено передавать управление исходному обработчику из myHandler, но этого делать не стоит, т.к. стандартный обработчик данного прерывания завершает работу программы, вызвавшей прерывание. В таком случае исходный вектор прерывания не был бы восстановлен со всеми последствиями.