Министерство образования и науки РФ

Новосибирский Государственный Технический Университет

Кафедра ВТ

Курсовая работа

по дисциплине: «Программирование»

«Резидентные программы и их организация»

Факультет: АВТ

Группа: АМ-515

Вариант: 17

Преподаватель:

Студент:

Новосибирск,

2007 г.


Цель работы: «Научиться создавать резидентные программы, осуществляющие перехват пользовательских прерываний в MS-DOS». Задание: разработать резидентную программу динамического дампа сегментных регистров регистра флагов и программного счётчика, активизируемую через вектор 03h. Содержимое регистров выводится на экран в 16-теричном коде. разработать резидентную программу динамического дампа регистров общего назначения, активизируемую через вектор 03h. Содержимое регистров выводится на экран в 16-м коде.
Структура резидентной программы:

Резидентная программа, это программа, остающаяся в памяти после её завершения.

При запуске программы управление передаётся (в соответствии с параметром директивы End) на начало процедуры resident. Командой jmp сразу же осуществляется переход на секцию инициализации.

Секция инициализации:

В секции инициализации подготавливаются условия для работы программы в резидентном состоянии, т. е. осуществляется переопределение векторов прерываний. Это необходимо для того, чтобы было возможно в дальнейшем обратиться к резидентной программе через вызов прерывания от пользователя. Резидентная программа в данном случае является пассивной, т. к. активизируется вызовом прерывания int в тестирующей программе.

НЕ нашли? Не то? Что вы ищете?

В начале секции вызывает функция 0 мультиплексного прерывания для проверки наличия в памяти ранее установленной копии резидентной программы. Это действие необходимо во избежание повторной установки программы, вызывающей дальнейшую некорректную работу. Мультиплексное прерывание предоставляет программисту удобный инструмент контроля резидентными программами.

Если программа ранее не была установлена, происходит ее установка с сохранением адресов текущих обработчиков (это действие необходимо для обеспечения работы системы после выгрузки программы из памяти) и переопределением их на новые адреса, по которым располагаются прикладные процедуры-обработчики.

Иначе, если программа была ранее установлена, проверяется состояние командной строки на наличие в ней параметра выгрузки резидентной программы из памяти. Если параметр найден, программа успешно выгружается.

Процесс выгрузки осуществляется вызовом функции 1 мультиплексного прерывания, которая восстанавливает переопределенные адреса обработчиков прерываний, затем освобождает память, занимаемую резидентной программой, и возвращает ее операционной системе.

Если параметр выгрузки не найден, на экран пользователя выводится уведомляющее сообщение о попытке переустановки резидентной программы и программа завершается.

В конце секции инициализации вызывается прерывание int 27h. Секция инициализации располагается в конце программы и отбрасывается при её завершении. Прерывание 27h, закрепив за резидентной частью программы необходимую для её функционирования память, передаёт управление командному процессору DOS.

Секция резидента:

После возврата управления операционной системе секция резидента остается в адресном пространстве операционной системы. В этой секции располагаются процедуры-обработчики, адреса старых обработчиков и все остальные данные необходимые для корректной работы программы после ее установки и после ее выгрузки из памяти.


Структура тестирующей программы:

Тестирующая программа состоит из блока, осуществляющего вывод на экран текущего состояния регистров общего назначения и блока вызова прерывания int3.

В тестирующей программе выводятся регистры(с использованием стека) до вызова обработчика.

Вызывается прерывание int3, которое выводит на экран содержимое регистров общего назначения, с корректированным регистром sp, т.к. при вызове данные сохраняются в стек и тем самым изменяют этот регистр.


Функциональное описание программы:

Макросы:

Прототип: SetXY xCord, yCord

Действие: установка регистра di на область видеопамяти соответствующую координатам (xCord, yCord)

Описание: в регистр di записывается адрес, вычисляемый по формуле xCord * 2 + yCord * 160

Прототип: InitScr sColor

Действие: инициализация экрана заданного цвета (sColor)

Описание: вызывается 6 функция 10h прерывания для вывода на весь экран окна заданного цвета

Прототип: InitWnd wColor, xCord, yCord, wWidth, wHeight

Действие: инициализация окна на экране заданного цвета (wColor) и заданных размеров (wWidth, wHeight) в положение, определяемое координатами (xCord, yCord)

Описание: вызывается 6 функция 10h прерывания для вывода на экран окна заданного цвета и размеров

Прототип: PrintText tColor, txCord, tyCord

Действие: вывод текста заданного цвета (tColor) на экран в положение, задаваемое координатами (txCord, tyCord)

Описание: непосредственным программированием видеопамяти выводится строка на экран. Адрес ASCIIZ-строки передается через регистр si. Регистр di настраивается на область видеопамяти макросом SetXY в соответствии с координатами (txCord, tyCord)

Прототип: PrintText txCord, tyCord

Действие: вывод текста на экран в положение, задаваемое координатами (txCord, tyCord)

Описание: действие макроса аналогично действию макроса PrintText tColor, txCord, tyCord за исключением того, что атрибут текста задается первым байтом строки, адрес которой передается через регистр si.

Процедуры:

Преобразование двоичного числа в шестнадцатеричное ASCII число: BinToHex

Процедура получает в регистре AX двоичное число, подлежащее преобразованию, а в регистре BX адрес 4 байтного буфера для формирования ASCII числа. Алгоритм преобразования реализует схему Горнера. В цикле число делится на основание системы счисления, т. е.16, а остатки от деления числа преобразуются в соответствующие ASCII цифры, которыми заполняется буфер.

Если остаток – цифра меньше 10, то для получения ASCII цифры к числу прибавляется код ‘0’, т. е. 30, если же число больше или равно 10, то для получения ASCII цифры к числу прибавляется код ‘7’, т. е. 37.

На выходе процедуры в буфере сформировано шестнадцатеричное ASCII число.

Обработчик прерывания int3: new_03

Процедура осуществляет вывод на экран содержимого регистров общего назначения.

Регистры сохраняются в стек, а потом из стека переводятся в строковый формат и выводятся на экран.

Для каждого из полученных значений вызывается процедура BinToiHex для преобразования их значений к шестнадцатеричному представлению ASCII числами.

Данные выводятся на экран.

Для каждого из регистров производится вывод подсказки(что это за регистр) и самого значения. Важно скорректировать регистр sp, так как он при прерывании изменяется, так как в стек помещается точка возврата и другая информация.

Выход из процедуры производится нажатием любой клавиши.

Обработчик прерывания int 2Fh: new_2F

Процедура сочетает в себе две функции: проверка резидента в памяти, удаление резидента из памяти.

Процедура проверяет, для какого резидента вызывается функция, если для «своего», то выполняются дальнейшие проверки, если для «чужого», вызов передается по цепочке другим мультиплексным обработчикам.

Когда вызывается 0 функция, то процедура возвращает 0FFh если резидент установлен, и 0 если резидент не установлен.

Когда вызывается 1 функция, производится удаление резидента из памяти, т. е. восстанавливаются переопределенные векторы прерываний, освобождается память занимаемая резидентной программой и передается управление в вызывающую прерывание программу.


Демонстрация работы программы:

Рис. 1. Запуск тестирующей программы до установки резидентной программы

Рис. 2. Запуск резидента, перезапуск, выгрузка резидента

Рис. 3. Работа тестирующей программы

Рис. 4. Работа пользовательского обработчика прерывания


Справочное описание системных обработчиков, сервисных функций DOS и BIOS:

Команда: INT номер прерывания

Действие: вызов прерывания

Описание: команда генерирует вызов подпрограммы обслуживания прерывания с номером, заданным операндом команды. В реальном режиме команда INT n записывает в стек регистр флагов FLAGS и адрес возврата – содержимое регистров CS и IP. Сбрасываются в ноль флаги IF, TF и AC, после чего управление передается программе обработки прерывания с номером n.

Команда: IRET

Действия: возврат из прерывания

Описание: В реальном режиме выполняется последовательное извлечение из стека содержимого регистров IP, CS, FLAGS, и работа прерванной программы возобновляется.

Команда: INT 27h

Действие: Оставить программу резидентной

Описание: На входе в DX адрес последнего байта резидентной части + 1.

Int 2Fh: мультиплексное прерывание.

Ввод: AH = функция прерывания или идентификатор программы (от 00h доFFh),

00h – 7Fh зарезервировано для DOS/Windows

B8h – BFh зарезервировано для сетевых функций,

C0h – FFh отводится для использования в прикладных программах,

AL = подфункция с кодом 00h – проверка наличия программы в памяти, остальные коды – свои для каждой функции,

BX, CX, DX=00h (если через эти регистры происходит возврат заранее обусловленных кодов)

Возврат: если при вызове прерывания Int 2Fh из инициализационной части резидентной программы (AH –принятый идентификатор программы, а AL=00h), происходит возврат в регистре AL значения FFh, то обработчиком обнаружено в памяти установленная ранее копия программы с “нашим” идентификатором. Возврат же с AL=00h – её отсутствие).

Int 21h, функция 49h. Освобождение блока памяти.

Освобождает блок памяти и передаёт его системе.

Вызов: AH=49h,

ES= сегментный адрес освобождаемого блока

Int 21h, функция 09h. Вывод строки.

Выводит строку символов на устройство стандартного вывода (используется в системных программах для вывода на экран информационных сообщений). Строка должна заканчиваться символом $ (код 24h), который служит признаком конца строки, и сам не выводится. Допустимо перенаправление вывода. В сообщение могут быть включены и управляющие коды (07h, 08h, 09h, 0Ah, 0Dh), которые вызывают соответствующие им действия (см. функцию 02h). Допустимо использование Exc-последовательностей. Функция выполняет обработку <Ctrl/C> при вводе этой комбинации с клавиатуры перед выводом каждого 64-го символа.

Int 10h, функция 00h. Установка видеорежима текущей видеостраницы с очисткой экрана (быстрая очистка экрана реализуется функцией 06h и 07h).

Вызов: AH = 00h,

Al = видеорежим (код режима задаётся в младших 7 битах, установка в 1 старшего бита запрещает очистку экрана).

Вызов разрушает регистры AX, BP, SI, и DI.

Int 10h, функция 05h. Установка видеостраницы.

Устанавливает активную видеостраницу (как текстовую, так и графическую).

Вызов: AH= 05h, AL= номер страницы (0,...,7).

Вызов разрушает регистры AX, BP, SI и DI.

Программа, устанавливающая страницу, отличную от текущей, обязана по окончанию работы восстанавливать исходную.

Функция 06h (07h). Инициализация или прокрутка окна вверх (вниз).

Инициализирует окно, с указанными координатами, пробелами ASCII с заданным атрибутом (AL = 0), или прокручивает содержимое окна вверх (вниз) на заданное число строк (AL = число строк). При прокрутке, появляющиеся снизу (сверху) строки, заполняются пробелами ASCII с заданным атрибутом. Функцию удобно использовать для быстрой очистки экрана или некоторого прямоугольного окна.

Вызов: AH = 06h(07h);

AL = 0 – очистка, AL = N (N >0) – прокрутка на N строк;

BH = атрибут символов в окне;

CH, CL = координаты строки и столбца (Y, X) левого верхнего угла;

DH, DL = координаты строки и столбца (Y, X) правого нижнего угла.

Вызов разрушает регистры AX, BP, SI, и DI.

Функция 01h (11h). Поверка буфера клавиатуры на наличие в нём символа.

Определяет, имеются ли в кольцевом буфере ожидающие ввода символы; возвращает флаг ожидания и сам символ при его наличии. Однако символ и его скан-код не извлекаются из буфера и могут быть снова получены при повторном вызове функции 00h Int 16h. Данная функция относится к числу асинхронных: определив состояние буфера ввода, она возвращает управление программе.

Вызов: AH = 01h (83/84-key), 11h(101/102-key).

Возврат: ZF = 1, если буфер пуст и ZF = 0, если в буфере имеется ожидающий считывания символ. В этом случае:

AL = ASCII-код символа/00h, AH = скан-код клавиши/расширенный ASCII-код.

Функция 11h (AH = 11h) – усовершенствованный вариант функции 01h для расширенной клавиатуры (101/102-key). Позволяет получить расширенные ASCII-коды для клавишей F11, F12, а также для ряда других комбинаций. В качества признака управляющих клавиш или их комбинаций, помимо значения 00h, используются 0Ah, 0Dh и E0h.


Вывод:

В данной работе была решена задача создания резидентного процесса. Что показало возможность имитации многозадачности средствами однозадачной операционной системы DOS.

Резидентная программа может быть как активной, так и пассивной. Активный резидент перехватывает аппаратные прерывания, а пассивный резидент активизируется при вызове прерывания int в пользовательской программе».

Из-за сложности и множества проблем связанных с резидентными программами, их редко применяют в операционной системе DOS, что ограничивает зону применению этой ОС и самого компьютера в целом.

Данные проблемы были решены в других, многозадачных операционных системах.


Листинг программы:

Резидентная программа

TITLE 'KURS - резидентная программа'

IDEAL

MODEL TINY

P486N

; Макрос установки позиции симвла на экране

; Аргументы: кординаты x, y

MACRO SetXY xCord, yCord

push ax bx

mov di, xCord

shl di,1

mov ax, yCord

mov bl, 160

mul bl

add di, ax

pop bx ax

ENDM SetXY

; Макрос инициализации экрана

; Аргументы: цвет экрана

MACRO InitScr sColor

mov ah, 6

mov al, 0

mov bh, sColor

mov cl, 0

mov ch, 0

mov dl, 79

mov dh, 24

int 10h

ENDM InitScr

; Макрос вывода строки на экран заданного атрибута

; Аргументы: цвет текста, координаты x, y

MACRO PrintText tColor, txCord, tyCord

LOCAL NextSym, Quit

push di ax

SetXY txCord, tyCord

mov ah, tColor

cld

NextSym:

lodsb

cmp al, 0

jz Quit

stosw

jmp NextSym

Quit:

pop ax di

ENDM PrintText

; Определение цветов экрана, текста и выделенного текста

SCRCOLOR = 0F4h

TCOLOR = 0F4h

STCOLOR = 0Ch

CODESEG

org 100h

; Главная процедура программы

PROC Resident

jmp Initialize ; переход на секцию инициализации

old_2F DD 0 ; адрес старого обработчика прерывания 2Fh

old_03 DD 0 ; адрес старого обработчика прерывания 03h

; Новый обработчик мультиплексного прерывания 2Fh

PROC new_2F

cmp ah, 0C0h ; наша функция?

jne Out_2F

cmp al, 0 ; вызвана функция проверки наличия обработчика в памяти?

je InMemory

cmp al, 1 ; вызвана функция удаления обработчика из памяти?

je Uninstall

Out_2F:

jmp [dword cs:old_2F] ; перебросить прерывание, если не наша функция

InMemory:

mov al, 0FFh ; программа уже установлена

iret ; возврат из прерывания

Uninstall:

push ds

push es

push dx

mov ax, 252Fh ; установка старого обработчика прерывания 2Fh

lds dx, [cs:old_2F]

int 21h

mov ax, 2503h ; установка старого обработчика прерывания 2Fh

lds dx, [cs:old_03]

int 21h

mov es, [cs:2Ch] ; освобождение памяти от переменных окружения

mov ah, 49h

int 21h

push cs

pop es

mov ah, 49h ; освобождение памяти, занимаемой программой

int 21h

pop dx

pop es

pop ds

iret ; возврат из прерывания

ENDP new_2F

; Новый обработчик прерывания 03h

PROC new_03

push bp

push ds

push es

push ax bx cx dx

mov ax, sp

add ax, 10

push ax bp si di

mov bp, sp

mov ax, cs ; настройка сегмента данных на сегмент кода

mov ds, ax

mov ax, 0B900h ; настройка сегментного регистра ES на 1 страницу видеопамяти

mov es, ax

mov ah, 0 ; инициализация 3 текстого режима

mov al, 3

int 10h

mov ah, 5 ; установка активной 1 видеостраницы

mov al, 1

int 10h

InitScr SCRCOLOR ; инициализация экрана цветом

; вывод на экран текстовых сообщений

mov si, offset iMsg0

PrintText TCOLOR, [x_zag], [y_zag]

mov si, offset iMsg1

PrintText TCOLOR, [x_text], [y_text]

;--

; Вывод на экран дополнительной информации(названий регистров)

push [x_mes] [y_mes]

mov cx, nvregs

mov si, offset mes_ax

cicl_mes:

push si

PrintText TCOLOR, [x_mes],[y_mes]

pop si

add si, mes_len + 1

add [y_mes],1

loop cicl_mes

pop [y_mes] [x_mes]

;--

; вывод значений регистров из стека

mov di, nvregs*2-2 ; начало "нашего" стека

push [x_mes] [y_mes]

add [x_mes], mes_len

mov cx, nvregs

cicl_regs:

mov ax, [word bp + di] ; получение из стека

mov bx, offset mes_buf

call BinToHex ; преобразуем значение регистра ax в ASCII число

lea si, [mes_buf]

mov [si+4],0

PrintText TCOLOR, [x_mes],[y_mes]

sub di,2

add [y_mes],1

loop cicl_regs

pop [y_mes] [x_mes]

;--

mov si, offset iMsg4

mov ah, [byte si]

inc si

PrintText TCOLOR, 10, 24

; проверка нажатия любой клавиши для выхода

REPEAT:

mov ah, 11h

int 16h

jz REPEAT

mov ah, 5 ; восстановление видеостраницы 0

mov al, 0

int 10h

pop di si ax ax dx cx bx ax

pop es ; восстановление сегментных регистров

pop ds

pop bp

iret ; возврат из прерывания

; данные обработчика

nvregs = 8 ; кол-во выводимых регистров

mes_ax db "AX = 0x",0

mes_bx db "BX = 0x",0

mes_cx db "CX = 0x",0

mes_dx db "DX = 0x",0

mes_sp db "SP = 0x",0

mes_bp db "BP = 0x",0

mes_si db "SI = 0x",0

mes_di db "DI = 0x",0

mes_len = $-mes_di-1

x_mes dw 21

y_mes dw 1

mes_buf db 80 dup('