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

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, но этого делать не стоит, т.к. стандартный обработчик данного прерывания завершает работу программы, вызвавшей прерывание. В таком случае исходный вектор прерывания не был бы восстановлен со всеми последствиями.