- •Отчёт о лабораторной работе №5
- •1. Стандартный обработчик int0
- •2. Замена стандартного обработчика int0 с использованием функций dos 25h и 35h
- •3. Замена стандартного обработчика int0 без использования функций dos 25h и 35h
- •4. Передача управления обработчику bios
- •5. Трассировка фрагмента программы
- •6. Сброс т-бита в обработчике int1
- •7. Использование вызовов прерываний по точке останова для ограничения трассируемого фрагмента программы
3. Замена стандартного обработчика int0 без использования функций dos 25h и 35h
Файл p1-3.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 al,0 ;номер прерывания
call getVec
mov stdOfs,bx ;сохранить смещение
mov stdSeg,es ;сохранить сегментный адрес
;задание собственного вектора
push ds
mov dx,offset myHandler
mov ax,seg myHandler
mov ds,ax
mov al,0
call setVec
pop ds
;инициация прерывания
divide: mov ax,1234h
mov bl,0
div bl ;делим ax на bl
mov ah,9
mov dx,offset mess2
int 21h
;восстановление стандартного вектора прерывания
push ds
mov dx,stdOfs
mov ax,stdSeg
mov ds,ax
mov al,0
call setVec
pop ds
mov ah,9
mov dx,offset mess3
int 21h
jmp divide
ret
begin endp
getVec proc
push ax
push cx
push di
mov ah,0
mov di,ax
mov cl,2
shl di,cl ;адрес вектора прерывания
mov ax,0
mov es,ax
mov bx,es:[di] ;записываем смещение
mov ax,es:[di]+2 ;записываем адрес сегмента
mov es,ax
pop di
pop cx
pop ax
ret
getVec endp
setVec proc
cli
push ax
push cx
push di
push es
mov ah,0
mov di,ax
mov cl,2
shl di,cl
mov ax,0
mov es,ax
mov es:[di],dx ;смещение
mov es:[di]+2,ds ;сегмент
pop es
pop di
pop cx
pop ax
sti
ret
setVec 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 25h и 35h. Процедура getVec записывает в BX значение из ячейки по адресу AL*4 (смещение) и в ES значение из ячейки по адресу AL*4+2 (сегментный адрес). Процедура setVec пересылает значение из DX в ячейку по адресу AL*4 и из DS в ячейку по адресу AL*4+2. Результат:
C:\MASM611\BIN>p1-3.exe
Произошло деление на ноль!
Вышли из обработчика.
Стандартный обработчик восстановлен. Проверка:
Your program caused a divide overflow error.
If the problem persists, contact your program vendor.
4. Передача управления обработчику bios
Организуем передачу управления стандартному обработчику после выполнения всех команд прерывания. Перед передачей управления восстановим адрес стандартного обработчика в таблице прерываний.
Файл p1-4.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 al,0 ;номер прерывания
call getVec
mov stdOfs,bx ;сохранить смещение
mov stdSeg,es ;сохранить сегментный адрес
;задание собственного вектора
push ds
mov dx,offset myHandler
mov ax,seg myHandler
mov ds,ax
mov al,0
call setVec
pop ds
;инициация прерывания
divide: mov ax,1234h
mov bl,0
div bl ;делим ax на bl
begin endp
getVec proc
push ax
push cx
push di
mov ah,0
mov di,ax
mov cl,2
shl di,cl ;адрес вектора прерывания
mov ax,0
mov es,ax
mov bx,es:[di] ;записываем смещение
mov ax,es:[di]+2 ;записываем адрес сегмента
mov es,ax
pop di
pop cx
pop ax
ret
getVec endp
setVec proc
cli
push ax
push cx
push di
push es
mov ah,0
mov di,ax
mov cl,2
shl di,cl
mov ax,0
mov es,ax
mov es:[di],dx ;смещение
mov es:[di]+2,ds ;сегмент
pop es
pop di
pop cx
pop ax
sti
ret
setVec endp
myHandler proc
mov dx,offset mess
mov ah,9
int 21h
push ds
mov dx,stdOfs
mov ax,stdSeg
mov ds,ax
mov al,0
call setVec
pop ds
jmp dword ptr stdOfs
myHandler endp
codesg ends
end begin
Как было отмечено выше, стандартный обработчик int0 завершает программу, в которой было выполнено деление на ноль. Поэтому после перехода на него в программе нет ни одной команды. Запустим эту программу и затем запустим первую программу, чтобы убедиться, что стандартный обработчик восстановлен правильно:
C:\MASM611\BIN>p1-4.exe
Произошло деление на ноль!
Your program caused a divide overflow error.
If the problem persists, contact your program vendor.
C:\MASM611\BIN>p1-1.exe
Your program caused a divide overflow error.
If the problem persists, contact your program vendor.