Министерство образования и науки РФ
Новосибирский Государственный Технический Университет
Кафедра ВТ
Курсовая работа
по дисциплине: «Программирование»
«Резидентные программы и их организация»
Факультет: АВТ
Группа: АМ-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('


