Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО отчёт №5.docx
Скачиваний:
9
Добавлен:
16.04.2015
Размер:
70.18 Кб
Скачать

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.