Смекни!
smekni.com

Резидентный обработчик клавиатуры (перехват нажатий клавиш и запись в файл) (стр. 1 из 7)

Министерство образования Украины

Одесская государственная академия холода
Институт информационных технологий

Кафедра «Информационных систем»

Разработка резидентного обработчика прерываний от клавиатуры

Курсовой проект по дисциплине

«Системы программирования и операционные системы»

Руководитель Ненов А. Д. Исполнитель

Ст. гр. 333А Лазанюк А. С.

Зач. книжка № 983214

Защищён с оценкой _____________________

(личная подпись)

_______________

г. Одесса 2000 г.

Содержание:

1. Задание……………………………………………………………………………………………….2

2. Краткие теоретические сведенья

2.1. Резидентный обработчик прерываний………………………………………………………...3

2.2. Защита резидентной программы от повторной установки…………………………………..5

2.3. Выгрузка резидентной программы из памяти………………………………………………...8

2.4. Перехват прерываний…………………………………………………………………………11

2.5. Обработчик прерываний………………………………………………………………………12

2.6. Прерывания от внешних устройств…………………………………………………………..12

2.7. Резидентный обработчик прерываний от клавиатуры с подключением до системного обработчика…………………………………………………………………………………….14

3. Описание программы

3.1. Описание для пользователя…………………………………………………………………...19

3.2. Описание для программиста………………………………………………………………….20

3.3. Листинг программы………………………………………………………………………..….24

3.4. Рекомендации по улучшению………………………………………………………………...32

4. Список используемой литературы…………………………………………………………..….33

1. Задание

Разработка резидентного обработчика прерываний от клавиатуры с подключением до системного. Данный обработчик должен производить запись скэн-кодов всех нажимаемых клавиш, а также фиксировать байт флагов клавиатуры при каждом нажатии. Обработчик должен иметь механизм выгрузки из оперативной памяти встроенный в него самого. Также программа должна иметь защиту от повторной установки в оперативную память.

2. Краткие теоретические сведенья

2.1. Резидентный обработчик прерываний

Большой класс программ, обеспечивающих функционирование вычислительной системы (драйверы устройств, программы шифрации и защиты данных, русификаторы, обслуживающие программы типа элек­тронных блокнотов или калькуляторов и др.), должны постоянно нахо­диться в памяти и быстро реагировать на запросы пользователя или на какие-то события, происходящие в вычислительной системе. Такие программы носят названия программ, резидентных в памяти (Terminate and Stay Resident, TSR), или просто резидентных программ. Сделать ре­зидентной можно как программу типа СОМ, так и программу типа

ЕХЕ, однако ввиду того, что резидентная программа должна быть мак­симально компактной, чаще всего в качестве резидентных используют программы типа СОМ.

Рассмотрим типичную структуру резидентной программы и систем­ные средства оставления ее в памяти после инициализации (рис. 2.1).

text segment 'code'

assume CS:text,DS:text

org 100h main proc

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

; Данные резидентной секции программы

. . .

entry: ; Текст резидентной секции программы

. . .

main endp

init proc ;Секция инициализации

. . .

mov DX, (init-main+10Fh)/16;Paзмер в параграфах

mov АН,3100h ;функция "Завершить и оставить в

int 21h ; памяти" init endp text ends

end main

Рис 2.1. Типичная структура резидентной программы.

Программа пишется в формате СОМ, поэтому в ней предусматри­вается только один сегмент, с котором связываются сегментные ре­гистры CS и DS; в начале сегмента резервируется l00h байт дня PSP.

При запуске программы с клавиатуры управление передается (в со­ответствии с параметром директивы end) на начало процедуры main. Командой jmp сразу же осуществляется переход на секцию инициализа­ции, которая может быть оформлена в виде отдельной процедуры или входить в состав процедуры main. В секции инициализации, в частности, подготавливаются условия для работы программы уже в ре­зидентном состоянии. Последними строками секции инициализации вызывается функция DOS 31h, которая выполняет завершение програм­мы с оставлением в памяти указанной ее части. Эта функция не может оставлять резидентными программы размером больше 64 Кб, но многие программы, написанные на ассемблере, соответствуют этому усло­вию. Так как резидентные программы уменьшают объем основной памяти, их все­гда пишут на ассемблере и оптимизируют для достижения минимального размера.

Размер резидентной части программы (в параграфах) передается DOS в регистре DX. Опре­делить размер резидентной секции можно, например, следующим обра­зом. К разности смещений mil-main, которая равна длине резидентной части программы в байтах, прибавляется размер PSP (l00h) и еще число 15 (Fh) для того, чтобы после целочисленного деления на 16 результат был округлен в большую сторону.

С целью экономии памяти секция инициализации располагается я конце программы и отбрасывается при ее завершении.


Точка входа ® main

при загрузке jmp init

. Резидентные

: поля данных Резидентная часть

Точка входа ® entry программы

при вызове . Резидентные

: коды

iret

init

. Секция

: инициализации Завершение программы

Функция DOS 31h ® с составлением в памяти

её резидентной части

Рис. 2.2 Взаимодействие элементов резидентной программы.

Функция 31h, закрепив за резидентной программой необходимую для ее функционирования память, передает управление командному процессору и вычислительная система переходит в исходное состояние. Наличие программы, резидентной в памяти, никак не отражается на хо­да вычислительного процесса, за исключением того, что уменьшается объем свободной памяти. Одновременно в память может быть загруже­но любое число резидентных программ.

На рис. 2.2 показаны элементы резидентной программы и их вза­имодействие.

Любая резидентная программа имеет по крайней мере две точки входа. При запуске с клавиатуры программы типа .СОМ управление всегда передается на первый байт после PSP (IP=l00h). Поэтому прак­тически всегда первой командой резидентной программы является ко­манда jmp, передающая управление на начало секции инициализации.

После отработки функции DOS 31h программа остается в памяти в пассивном состоянии. Для того, чтобы активизировать резидентную программу, ей надо как-то передать управление и, возможно, парамет­ры. Вызвать к жизни резидентную программу можно разными способа­ми, но наиболее употребительным является механизм аппаратных или программных прерываний. В этом случае в секции инициализации не­обходимо заполнить соответствующий вектор адресом резидентной части программы (точка entry на рис. 2.2). Адрес entry образует вторую точку входа в программу, через которую осуществляется ее активизация. Очевидно, что резидентная секция программы должна заканчиваться командой выхода из прерывания iret.

Поля данных резидентной части программы переместились в начало программы после команды imp. Это довольно естественное место дня резидентных данных, потому что и при первом запуске, и при активизации сюда никогда не будет передано управление. При заполнении в секции инициализации векторов не возникает проблем с перенастройкой регистра DS, так как в программе типа СОМ все регистры указывают на единственный сегмент програм­мы. В секции инициализации предусмотрен, как это обычно делается, вывод на экран сообщения о загрузке программы в память.

После запуска программы она остается в памяти и, активизируясь фактически аппаратными прерываниями от клавиатуры (а более точно – программой BIOS, активизируемой аппаратными прерываниями от клавиатуры).

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

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

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