Реферат: Системы программирования и операционные системы - текст реферата. Скачать бесплатно.
Банк рефератов, курсовых и дипломных работ. Много и бесплатно. # | Правила оформления работ | Добавить в избранное
 
 
   
Меню Меню Меню Меню Меню
   
Napishem.com Napishem.com Napishem.com

Реферат

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

Банк рефератов / Программирование

Рубрики  Рубрики реферат банка

закрыть
Категория: Реферат
Язык реферата: Русский
Дата добавления:   
 
Скачать
Архив Zip, 59 kb, скачать бесплатно
Заказать
Узнать стоимость написания уникального реферата

Узнайте стоимость написания уникальной работы

32 Министерство образования Украины Одесская государ ственная академия холода Институт информационных технологий Кафедра «Ин формационных систем» Разработка резидент ного обработчика прерываний от клавиатуры Курсовой проект по дисциплине «Системы программирования и о перационные системы» Руководитель Не нов А . Д. Исполнитель Ст . гр . 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 100 h main proc jmp init ;П ереход на секцию инициализации ; Данные р езидентной секции программы . . . entry : ; Текст резидентной секции программы . . . main endp init pro c ; Секция инициализации . . . mov DX , ( init - main +10 Fh )/16 ; Pa змер в параграфах mov АН, 3100 h ;функция "Завершить и оставить в int 21h ; памяти " init endp text ends end main Рис 2 .1. Типичная стр уктура резидентной программы. Программа пишется в формате СОМ , поэтому в ней предусматри вается только один сегмент , с котором связываются сегментные ре гистры CS и DS ; в начале сегмента резервируется l00h байт дня PSP. При за пуске программы с клавиатуры управлен ие передается (в со ответствии с параметром директивы end ) на начало процедуры main . Командой jmp сразу же осуществляется переход на секцию инициализа ци и , которая может быть оформлена в виде отдельной процедуры или входить в состав процедуры main . В секц ии инициализации , в частности , подготавлив аются условия для работы программы уже в ре зидентном состоянии . Последними строками с екции инициализации вызывается функция DOS 31 h , которая выполняет заве ршение програм мы с оставлением в памяти указанной ее част и . Эта функция не может оставля ть резидентными программы размером больше 64 Кб , но многие программы , написанные на ассем блере , соответствуют этому усло вию . Так как резидентные программы уменьшают объем основной памяти , их все гда пишут на ассемблере и опт имизируют для достижения минималь ного размера. Размер резидентной части программы (в параграфах ) передается DOS в регистре DX. Опре делить размер резидентной секции можно , например , следующим обра зом . К разности сме щений mil - main , которая равна длине рези дентной части программы в байтах , прибавляется размер PSP (l00h) и еще число 15 ( Fh ) для того , чтобы после целочисленного деления на 16 результат был округлен в большую сторону. С целью экон омии памяти секция инициализации располагается я конце программы и отбрасывается при ее завершении. Точка входа main при загрузке jmp init . Ре зидентные поля дан ных Резидентная часть Точка входа entry программы при вызове . Резидентные коды iret init . Секция инициализации Завершение программы Функция DOS 31 h с составлением в памяти е ё резидентной части Рис . 2.2 Взаимодействие элементов резидентной программы. Функция 31 h , закрепив за резидентно й програ ммой необходимую для ее функц ионирования память , передает управление командном у процессору и вычислительная система переход ит в исходное состояние . Наличие программы , резидентной в памяти , никак не отражается на хо да вычислительного процесса , за иск лючен и ем того , что уменьшается объ ем свободной памяти . Одновременно в память может быть загруже но любое число резидентн ых программ. На рис . 2.2 показаны элементы резидентной программы и их вза имодействие . Любая резидентная программа им еет по крайней мере две точки входа . При запуске с клавиатуры программы типа .СОМ управление всегда передается на первый бай т после PSP ( IP = l 00 h ). Поэтому прак ти чески всегда первой командой резидентной прог раммы является ко манда jmp , передающая управлени е на начало секции инициализации. После отработки функции DOS 31h программа остается в памяти в пассивном состоянии . Для того , чтобы активизировать рези дентную программу , ей надо как-то передать управление и , возможно , парамет ры . Вызвать к жизни резидентн ую программу можно разн ыми способа ми , но наиболее употребительным яв ляется механизм аппаратных или программных пр ерываний . В этом случае в секции инициализ ации не обходимо заполнить соответствующий вектор адресом резидентной части программы (точка entry н а рис . 2.2). Адрес entry образует вторую точку входа в прог рамму , через которую осуществляется ее активи зация . Очевидно , что резидентная секция програ ммы должна заканчиваться командой выхода из прерывания iret . Поля данных резидентной части программы перем естились в начало про граммы после команды imp . Это довольно естественное место дня резиде нтных данных , потому что и при первом запуске , и при активизации сюда никогда не будет передано управление . При заполнении в секции инициализации векторов не возникает проблем с перенастройкой регистра DS , так как в программе типа СОМ вс е регистры указывают на единственный сегмент програм мы . В секции инициализации предусмотр ен , как это обычно делается , вывод на э кран сообщения о загрузке программы в пам ять. После запус ка программы она остае тся в памяти и , активизируясь фактически а ппаратными прерываниями от клавиатуры (а боле е точно – программой BIOS , активизируемой аппаратными прерываниями от клавиатуры ). 2.2. Защита резиде нтной программы от повторной установки Как пра в ило , в секции инициализации загружаются векто ры прерываний , через которые будет активизиро ваться программа . Последними строками секции инициализации вызывается функция DOS 31 h , которая выполняет завершение прогр аммы с оставлением в памяти ее резидентно й ч асти. Если про грамму запустить с клавиатуры повторно , в память будет загружена и останется резидентно й ее вторая копия . Это плохо не только потому , что понапрасну расходуется память , более неприятным является вторичный перехват тех же векторов . Если резиде нтная программа после ее активизации не обращает ся к старому содержимому перехваченных ею векторов , то вторая копия полностью лишит первую работоспособности , и тогда повторная загрузка приведет только к расходованию па мяти . Если , однако , как это обычно и и меет место , резидентная программа в процессе своей работы передаст управлени е старому обработчику перехваченного ею преры вания , то новая копия резидентной программы , сохранившая в процессе инициализации адрес первой копии в качестве содержимого перехв атыв а емого вектора , будет при кажд ой активизации вызывать и первую копию . В результате резидентная программа будет факти чески выполняться при каждом вызове дважды . Во многих случаях такое повторное выполнен ие нарушит правильную работу программы . Поэто му обязат е льным элементом любой р езидентной программы является процедура защиты ее от повторной загрузки , или , как говор ят , установки. Наиболее распространенным методом защиты резидентной программы от повторной установки является исп ользование прерывания 2 Fh , специально предназначенного для связи с резидентными программами . При вызове этого прерывания в регистре АН задается номер функции (от 00h до FFh), а в регистре AL - номер подфункции (в том же диапазон е ). 00 h - 7 Fh зарезервировано для DOS / Windows 0 B 8 h - 0 B Fh зарезерви ровано для сетевых функций 0 C 0 h - 0 FFh отводится для программ . Для того , чтобы резидентная программа могла отозватьс я на вызов прерывания int 2Fh, в ней должен иметься обработчик этого прерывания . Фактически все резидентные программы , как сист емные , так и прикладные , имеют т акие обработчики , через которые осуществляется не только проверка на повторную установку , но и вообще связь с резидентной прог раммой : смена режима ее работы или получен ие от неё в транзитную программу каких-то параметров . З а дание действия , кот орое надлежит выполнить обработчику прерывания 2Fh конкретной резидентной программы , осуществляется с помощью номера подфункции , помещаемого перед вызовом прерывания в регистр AL Таким образом , обработчик прерывания 2Fh рез идентной прогр аммы должен , прежде всего , проверить номер функции в регистре АН ; при обнаружении "своей " функции обработчик ана лизирует содержимое регистра AL и выполняет зат ребованные действия , после чего командой iret передаст у правление вызвавшей его программе . Если , однако , обработчик обнаружил в регистре АН "чужую " функцию , он должен командой jmp CS : old _2 fh передать управление по цепочке тому обработчику , адрес которого был ранее в векторе 2Fh. В результате вызов int 2Fh из любой программы будет проходить по цепочке через все загруженные резидентные программы , пока не достигнет "своей " программы или не вернет управление в вызвавшую программу через обработчик DOS (который , очевидно , всегда будет самым последним в цепочке ). Естественно , для коммуникации с резидентн ой пр ограммой должен быть установлен некоторый интерфейс . Обычно при проверке на повторную установку резидентная программа , если она уже находится в памяти , возвращает в регистре AL значение FFh, которое является при знаком запрета вторичной загрузки . Иногда дл я большей надежности идентификации " своей " функции резидентная программа , помимо з начения FFh в регистре AL, возвращает еще какие-то обусловленные заранее коды в других реги страх . Часто через дополнительные регистры пе редастся символьная информация , наприм е р , имя программы . В этом случае , ес ли вызвавшая программа с именем DUMP . COM (т.е . вторая копия резидентной программы , выя сняющая , можно ли ей остаться резидентной в памяти ) получает после вызова int 2Fh в регист ре AL значение FFh, а в регистрах СХ и DX сим вольные коды ' DU ' и 'МР ', она может быть увере на , что ее первая копия уже находится в памяти. Есл и же в регистре AL вернулся код FFh, а в регистрах СХ и DX - коды , например , 'ОК ' и ' RB ', это , скорее всего оз начает , что закрепленная за нашей программой функц ия мультиплексного прерывания ухе используется другой резидентной программой . В этом случае стоит сменить функцию , чтобы не возбуждать конфликтных ситуаций. В резидентную часть следует включить обработчик прерывания 2Fh. Его расположение в пр еделах текста программы не имеет особог о значения ; мы поместили его в начале резидентной части . Секция инициализации претерпел а большие изменения . Она должна начинаться с вызова прерывания 2Fh с соответствующей фун кций для проверки на повторную установку . Если первая к о пия программы уже загружена , текущую программу следует завершить не функцией 3 th (завершить и оставить в памяти ), а обычной функцией з авершения 4 Ch . Если же нашей программы в памяти нет , то в секции инициализации , помимо заполнения ее " рабочего " вектора , в данном случае 03 h , следует также установи ть наш обработчик мультиплексного прерывания. Среди функций мультиплексного прерывания , предназначенных для прикладных программ , мы п роизвольно выбрали для нашей программы функци ю F 1 h , а для проверки на повторную установку подфункц ию 00 h . Резидентный обработч ик прерывания 2 Fh , включенный в нашу программу , проверяет номера функции и подфункции и при обна ружении каких-либо других кодов передает упра вление следующему обработчику этого прерывания . Если же вызвана функц ия F 1 h с подфункцией 00h, обработчик устанавливает в регистре AL значение FFh ("я уже загружен ") и возвращает управ ление в вызвавшую программу командой iret . Секция инициализации начинается с проверки на повторную установку . После загрузки в регистр АН ном ера функц ии ( F 1 h ), а в регистр AL - номера подфункции (00h), вызывается пре рывание 2Fh. После возврата из прерывания анализ ируется содержимое регистра AL Если обработчик вернул значение FFh, программа должна завершиться без оставления в памяти . Эти действи я выполняются по метке installed . Если возвращено другое значение , инициализация продолжается (для надежности с тоило проверить , возвращен ли именно 0). Сохраня ется старое содержимое вектора 2 Fh , устанавливается наш обработчик это го прерывания , после чего в ыполняются все действия по установке , предусмотренные в старом варианте программы динамического дамп а . При переходе на метку installed на экран выводится сообщение о невозможнос ти повторной установки и выполняется функция завершения 4С h с кодом возврата 0 1 h . Последнее , конечно , име ет символический характер , поскольку этот код в дальнейшем не анализируется . 2.3. Выгрузка рез идентной программы из памяти Следует заметить , что в DOS отсутствуют средства вы грузки резидентных программ . Единственный предусм отренн ый для этого механизм - перезагрузка компьютера . Практически , однако , большинство р езидентных программных продуктов имеют встроенные средства выгрузки . Обычно выгрузка резидентной программы осуществ ляется соответствующей ко мандой , подаваемой с клавиатуры и воспринимаемой резидентной программой . Для этого резидентная программа д олжна перехватывать прерывания , поступающие с клавиатуры , и "вылавливать " команды вы грузки . Д ругой , боже простой способ заключается в з апуске некоторой программы , которая с помощью, например , мультиплексного прерыва ния 2 Fh передает резидентной программе команду выгрузки . Чаще всего в качестве "выгружающей " используют саму резидентную про грамму , точне е , ее вторую копию , которая , если ее за пустить в опреде ленном режиме , не только не пытается остаться в памяти , но , на оборот , выгружает из памяти свою первую ко пию. Выгрузку резидентной программы из памяти можно осущ ествить разными способами . Наиболее простой - о свободить блоки памяти , за нимаемые программой (собственно программой и ее о кружением ) с помощью функции DOS 49 h . Другой , более сложный - использовать в выгру жающей программе функцию завершения 4 Ch , заставив ее завер шить не саму выгружающую , а резидентную програ мму , да еще после этого вернуть управление в выгружающую . В любом слу чае пер ед осво бождением памяти необходимо восстановить все векторы прерываний , перехваченные резиде нтной программой . Следует подчеркнуть , что вос становление векторов представляет в общем слу чае значительную и иногда даже неразрешимую проблему . Во-первых, старое содержимое в ектора , которое хранится где-то в полях да нных резидентной програм мы , невозможно извлечь "снаружи ", из другой программы , так как н ет никаких способов определить , где именно его спрятала резидентная программа в проце ссе инициализации . П оэтому выгрузку резидентной программы легче осуществить из не е самой , чем из другой программы . Во-вторых , даже если выгрузку осуществляет сама рез идентная про грамма , она может правильно восст ановить старое содержимое вектора лишь в том случае , если этот в ектор не был позже перехвачен другой резидентной программой . Если же это произошло , в табли це векторов находится уже адрес не выгруж аемой , а следующей резидентной про граммы , и если восстановить старое содержимое вектора , эта следующая программа "повиснет " , лишившись средств своего запуска . Поэтому н а дежно можно выгрузить только последнюю из загруженных резидент ных программ. В нашей программе подфункция 00 h прерывания 2Fh служит для проверки на повторную установку , а подфункция 01 h - для выгрузки . В секц и ю инициализации добавлены строки сохране ния старого содержимого вектора 09 h . Это выполняется точно так же , как и для вектора 2Fh - с помощью функции DOS 35 h . Старый вектор сохра ня ется в ячейке old _09 h , размещаемой в резидентной части программы . Поскольку выгрузка программы выполняется с помощью прерывания 2Fh, текст обработчика этого прерывания усложняется. Резидентный обработчик прерывания 2 Fh прежде всег о проверяет номер функции , поступивший в р егистре АН , Если этот номер от личается от F 1 h , управление п ередае тся следующему обработчику по цепочке . Далее анализируется содержимое регистра AL . Если AL =00 h , выполняются действия по защите от пов торной загрузки . Если AL =01 h , осуществляется переход на метку uninstall для выполнения действий по выгруз ке программы . При любом другом номере подфункции управле ние передается следующему о бработчику по цепочке. По метке uninstall осуществляется сохранение используемых далее регистров (что делается скорее для красоты , чем по н еобходимости ) и функцией DOS 25 h восстанавлив ается из ячеек old _09 h и old _2 Fh ис ходное содержимое соответствующих векто ров . Далее из ячейки со сме щением 2 Ch относительно начала PSP в регист р ES загружается адрес окружения про граммы . Сегментный адрес освобождаемого блока памя ти - единственный парам етр , требуемый для выполнения функции DOS 49 h . Размер освобождаемого блока DOS известен , он хранится в блоке управления памятью (МСВ ). Далее освобождается блок памяти с самой программой . Сегментный адрес этого бл ока (адрес PSP) находится в регистре CS . Нак онец , командой iret управление передастся в програм му , вызвавшую прерывание 2Fh. Функция 49 h оповещает DOS о том , что данный блок памяти сво боден и может впредь использоваться DOS . Это , однако , не меш ает вы полняться завершающим строкам программы (в данн ом случае – коман де iret), поскольку освобождени е памяти не разрушает ее содержимого . Наша резидентная программа физически сотрется лиш ь после того , как в память будет загру жена очередная выполняемая программа. Если про грамма запускается с клавиатуры с ук а занием каких-либо параметров (имен файлов , ключ ей , определяющих режим работы про граммы и проч .), то DOS , загрузив программу в память , помещает все символы , введенные после имени программы (так называ емый хвост команды ) в префикс программного сегмента про граммы , начиная с от носите льного адреса 80 h . Хвост команды помещается в PSP во вполне определенном формате . В байт по адресу 80h DOS заносят число сим волов в хвосте команды (включая пробел , разделяющий на к омандной строке саму команду и ее хвост ). Далее (начиная с байта по адресу 81 h ) следуют все символы , введенные с клавиатуры до нажатия клавиши < Enter >. Завершается хвост колом возврата каретки (13). К данным секции инициализации добавилась строка с ожидаемым хвостом команды и байтовый флаг запроса на вы грузку. Поскольку действия программы при её з апуске зависят от того , вве дена ли команд а запуска с параметром или нет , наличие хвоста в PSP анализ ируется в самом начале секции инициализации . При запуске программы типа СОМ все с егментные регистры указывают на начало PSP. Байт с длиной хвоста (возможно , нулевой ) п омещается в регистр CL и сравнивается с нулем . Если в нем 0, команда запуска была введена без параметров и инициализация программы прод олжается обычным образом . Если хвост имеет ненулевую длину , начи нается его анализ. Обнулением регистра СН длина хвоста "р асширяется " на весь ре гистр СХ , что нужно для организации цикла . Регистр DI настраивается на первый байт хвоста , а рег истр SI – на на чало поля tail с ожидаемой формой параметра . Регистр AL подготавл и вается для выполнения ко манды сканирования с троки . Команда scasb сравнивает в цикле байты хвоста с содержимым AL (кодом пробела ). Сравнение ведется до тех пор , п ока не будет найден первый символ , отличны й от пробела . Эта операция необходима из-з а того , ч то оператор при вводе ком анды вы грузки может отделить параметр команд ы от самой команды любым числом пробелов , которые попадут в хвост команды в PSP и помешают анализировать введенный параметр. Выход из цикла выполнения команды scasb о существляется , когда команда проанализировала первый после пробела символ . После этого регистр DI указывает на второй символ параме тра . Команда dec DI кор ректирует указатель DI, направляя его на первый значащий символ вве денного параметра . Далее командой сравнения строк cmp sb осу ществляется сра внение трех оставшихся символов хвоста . Если символы совпадают с параметром ' off ' , записанным в программе , устанавливается флаг запроса на выгрузку . Если результат сравнения оказался отрица тельным , флаг запроса не устанавливается (и , следовательно , не пра вильный параметр просто не воспринимается ). В любой случае осу ществляется переход на продолжение программы , начинающей прове рять , не установлена ли уже эта программа в памяти . Если программа еще не установлена , введенный параметр н е имеет смыс ла . Инициали зация осуществляется обычным образом : сохраняются и устанавливают ся векторы и программа завершается с оставлением в памя ти. При нали чии в памяти резидентной копии этой прогр аммы осу ществляется переход на метку installed , где преж де все го проверяется , установлен ли флаг запроса на выгрузку . Если флаг сброшен , выводится сообщение о невозможности повторной загрузки и программа завер шается с кодом возврата 1. Если флаг запроса установлен , выполняется выгрузка программы , которая закл ю ча ется в вызове мультиплексного прерывания 2 Fh с функцией F 1 h и подфункцией 01 h . Резидентный об работчик этого прерывания , включенный в состав наш ей резидентной программы , отработает эту подф ункцию , восстано вит векторы и освободит занятые программой блоки памяти . После возврата управления из обработчика в текущую программу будет выведено сообщение об успешной выгрузке и программа будет завер шена функцией 4 Ch с нулевым кодом возврата. Составленна я нами программа не избавлена от недостат ков . Так , в ней анали зируются всегда только 3 значащих символа хвоста . Таким об ра зом , программа будет выгружена и при вводе команды ( имя ). com onset . Другой недостаток заключается в том , что результат сравне ния записанного в программе хвоста с введенным с клавиатуры пара метр ом будет положительным , только если с клавиатуры введены строчные буквы . Команда ( имя ) OFF не приведет к выгрузке про граммы . П о-настоящему следовало включить в программу п еред анали зом хвоста преобразование символов параметра в прописные буквы . 2.4. Пер ех ват прерываний В архитекту ре процессоров 80х 86 предусмотрены особые случаи , когда процессор прекращает (прерывает ) выполнение тек ущей программы и немедленно передает управлен ие программе-обработчику , специально написанной дл я обработки подобной ситуа ции . Такие о собые ситуации делятся на два тина : прерыв ания и исключения , в зависимости от того , вызвало ли эту ситуацию какое-нибудь вне шнее устройство или выполняемая процессором к оманда . Исключения делят ся далее на три т ипа : ошибки , ловушки и остановы, в зависимости от того , когда по отношению к вызвавшей их команде они происходят . Ошибки появляются перед выполнением команды , поэтому обработчик такого исключения получит в качестве адреса возврата адрес ошибочной команды (начиная с процессоров 80286). Лов ушки происходят сразу после выполнения команды , та к что обработчик получает в качестве адре са возврата адрес следующей команды . И нак онец , остановы могут возникать в любой мом ент и вообще не предусматривать средств в озврата управления в программу. Команда INT (а также INTO и INT 3) используется в программах как раз для того , чтобы вызы вать обработчики прерываний (или исключений ). Ф актически они являются исключениями ловушки , поскольку адрес возврата , который передастся обработчику , указывает на следующую ком ан ду , но так как эти команды были введен ы до разделения особых ситуаций на прерыв ания и исключения , их практически всегда н азывают командами вызова прерываний . Ввиду то го , что обработчики прерываний и исключений в DOS обычно не различают механизм вызова , с помощью команды INT можно передава ть управление , как на обработчики прерываний , так и исключений . Как показано в глав е 4, программные прерывания , то есть передача управле ния при помощи команды INT , являются основным средством вызова процедур DOS и BIOS , потому что в отличие от вызова через команд у CALL здесь не нужно знать адреса вызываемой процедуры - достаточно только номе ра . С другой сторо ны интерфейса рассмотрим , как строится обработчик программного прерывани я. 2.5. Обработчики прерываний Когда в реа льном режиме выполняется команда INT, управл ение передается по адресу , который считываетс я из специального массива , таблицы векторов пре рываний , начинающегося в памяти по адре су 0000 h :0000 h . Каждый элемент тако го массива представляет собой дальний адрес обработчика прерывания в форма те сегмент :смещение или 4 нулевых байта , если обработ чик не установлен . Команда INT помещает в сте к регистр флагов и дальний адрес возврата , поэтому , чтобы завершить обработчик , надо выполнить команды popf и retf или одну ко манду iret , которая в реальном режиме п олностью им аналогична. После того как обработчик написан , следующий шаг - привязка его к выбран ному номеру прерыван ия . Это можно сделать , прямо записав его адрес в таблицу векторов прерываний. Хотя прямое изменение та блицы векторов прерываний и кажется достаточн о удобным , все-таки это не лучший подход к установке обработчика прерывания , и польз оваться им следует только в исключительных случаях , например , внутри обработчиков прерыван ий . Для обычных программ DOS предос тавляет две сис темные функции : 25 h и 35 h - уста новить и считать адрес обработчика прерыва ни я , которые и рекомендуются к использованию в обычных условиях . Обычно обработчики прерываний применяют с целью обработки прерывания от внешних ус тройств или с цел ью обслуживания запр осов других программ. 2.6. Прерывания о т внешних устройств Прерывания от внешних устройств или аппаратные прерывания , - это то , что понимается под термином «прерывание» . Внешние устройства (клавиатура , диско вод , таймер , звуковая карта и т . д .) подают сигнал , по которому процессор преры вает выполнение программы и передает управлен ие на обработчик прерывания . Всего на перс ональных компьютерах используется 15 аппаратных пре рываний , хотя теоретически возможности архитектур ы позволяют довес т и их число до 64. – IRQ 1 (INT 9) - прерывание клавиатуры , вызывается при каждом нажатии и отпускании клавиши на клавиатуре . Стандар тный обработчик этого преры вания выполняет д овольно много функций , начиная с перезагрузки по Ctrl - Alt - Del и заканчивая пом ещением кода клавиши в буфер клавиатуры BIOS . Самые полезные для программ аппаратные прерывания — прерывания систем ного таймера и клавиатуры . Так как стандартные обработчи ки этих прерываний выполняют множество функци й , от которых зависит работа системы , их нельзя заменять полностью . прерванной программ е . Этот способ применяют , если нужно , чтобы сначала отработал новый обработчик , а пот ом он передал управление старому Резидентные прог раммы , перехватывающие аппаратные прерывания , обла дают свойством выполн ятся одновременно с какой-либо другой программой . Именно для этого и применяется механизм аппаратных преры ваний - они позволяют процессору выполнять одн у программу , в то время как отдельные программы следят за временем , считывают симво лы из клавиату ры и п омещают их в буфер , получают и передают данные ч ерез последовательные и параллельные порты и даже обеспечивают многозадачность , переключая про цессор между разными задачами по прерыв анию системного таймера. Разумеется , обработка прерываний не должн а занима ть много времени : если прерыва ние происходит достаточно часто (например , пре рывание последователь ного порта может происходит ь 28 800 раз в секунду ), его обработчик обязател ьно должен выполняться за более короткое время . Если , например , обработчик пре рыв а ния таймера будет выполняться 1/32,4 секунды , то есть половину времени между прерываниям и , вся система станет работать в два р аза медленнее . А если еще одна программа с таким же долгим обработчиком перехвати т это прерыва ние , система остановится совсем . И м енно поэтому обработчики преры ваний при нято писать исключительно на ассемб лере. 2.7. Резидентный обработчик прерываний от клавиатуры с подключ ением до системного обработчика Практически л юбая программа , в которой предусмотрено управ ление ходом ее выполне ния с помощью команд , подаваемых с клавиатуры , имеет в своем составе обработчик прерываний от кла виатуры . В зависимости от стоящих перед ни м задач , обработчик может подключаться до системного , выполняя обработку скэн-кодов нажимаем ых клавиш , или после сис т емною , работая в этом случае с кодами ASCII . возникающими на выходе системного обработчика . Нередки случаи , когда прикладной обработчик выполняет часть своих функций до системного , а часть - посл е . Настоящая и несколько последующих статей посвящены этому в ажному для прикладног о программиста вопросу. Для того чтобы написать , обработчик прерываний от клавиатуры , необходимо хорошо представлять , каким образом вводятся , куда попадают и как обрабатываются символы , вводимые с клавиатуры . Процесс взаимодействия сис темы с кла виатурой показан на рис . 2 . 3 . IRQ INT Адрес системного Аппаратное Контроллер Микро - обработчика int 09h прерывание прерываний Вектор 09 процессор из вектора 09 на IRQ1 IRQ7 Запуск систем Нажатие или обработчика int09h отп ускание Байт флагов люб ой клавиши Системный клавиатуры Контроллер Порт 60h обработчик [40h:17h] клавиатуры Скэн-код int09h | 7 | 6| 5| 4| 3| 2| 1| 0| Клавиатура Ins Скэн-код Код Caps Lock Кольцевой буфер ASCII Num Lock 40h:1Eh вв ода Scroll Lock 40h:1Ah Alt Адрес головного Скэн ASCII Ctrl символа Скэн ASCII Shift левый Скэн ASCII Shift правый Пр ограмма Скэ н ASCII пользователя Адрес хвостового символа Запрос на ввод 40h:3Ch с кл авиатуры Ввод самого “старого” символа Рис . 2.3. Процесс взаимодействия системы с клавиатурой. Работой клавиатуры управляет с пециальная электронная схема - контроллер клавиату ры . В его функции входит распознавание наж атой клавиши и по мещение закрепленного за ней кода в свой выходной регистр (порт ) с номером 60 h . Код клавиши , поступающий в порт , называется скэн-кодом и является , по существу , порядк овым номером кла- виши . При этом каждой клавише присвоены два скэн-ко да , отличающиеся друг от друга на 80 h . Один скэн-код (меньший , код нажатия ) засылается контроллером в п орт 60h при нажатии клавиши , другой (больший , код отпускания ) - при ее отпускании. Скэн-код однозначно указывает на нажатую клавишу , одна ко , по нему нельзя определить , работа е т ли пользователь на нижнем или верхнем регистре . С другой стороны , скэн-коды присво ены всем клавишам клавиатуры , в том числе управляющим клавишам < Shift >, < Ctrl >, < Alt >, < Caps Lock > и др . Таким образом , очевидно , что определение введенного символа должно вк лючать в себя не только считывание скэн-ко да нажатой клавиши , но и выяснение того , не были ли перед этим нажаты , например , клавиши < Shift > (вер хний регистр ) или < Caps Lock > (фиксация верхнего регистра ). Всем этим анализом занимается программа обработки прерываний от клавиатуры. Как нажатие , так и отпускание любой клавиши вызывает сигнал аппаратного прерывания , заставляющий процессор прервать выполняемую программу и перейти на программу системного обработчика прерываний от клавиатуры , входящ его в систему BIOS . Поскольку обработчик вызывается через вектор 09 h , его иногда называют программой int 09 h . Программа int09h, помимо порта 60h, рабо тает еще с двумя областями оперативной па мяти : кольцевым буфером ввода , располагаемым п о адресам от 40 h : lEh до 40 h :3 Dh , к уда в конце концов помещаются коды ASCII нажатых клавиш , и б итом флагов клавиатуры , находящимся по адресу 40 h :17 h , где фиксируется состоя ние управляющих клавиш (< Shift >, < Caps Lock >, < Num Lock > и др .). Программа int09h, получив управление в результа те прер ывания от клавиатуры , считывает из порта 60h скэн-код и анализирует его зн ачение . Если скэн-код принадлежит одной из управляющих клавиш , и , к тому же , представл яет собой код нажатия , в байте флагов клавиатуры устанавливается бит (флаг ), соответствую щий на ж атой клавише . Например , при нажатии правой клавиши < Shift > в байте флагов устанавливается бит 0, при нажатии левой клавиши < Shift > - бит 1, при нажат ии любой клавиши < Ctrl > - бит 2 и т.д . Биты флагов сохраняют свое состояние , пока клавиши (по одиночке или в любых комбинациях ) остаются наж атыми . Если управляющая клавиша отпускается , п рограмма int09h получает скэн-код отпускания и сбра сывает соответствующий бит в байте флагов . Кроме состояния указанных клавиш , в байте флагов фиксируются еще режимы < Scroll Loc k >, < Num Lock >, < Caps Lock > и < Insert > (см . рис . 2 . 3 ). Компьютеры PC/AT имеют второй байт флагов клавиатуры , находящийся по адресу 40 h :18 h , и отражающий состояние управляющих клавиш на расширенной (101-клавишной ) клавиатуре . При нажа тии обычной , не управл яющей клавиши , п рограмма int 09 h считывает из порта 60 h ее скэн-код нажатия и по табли це трансляции скэн-кодов в коды ASCII формирует дву хбайтовый код , старший байт которого содержит скэн-код , а младший код ASCII . При этом если скэн-код характе ризует клавиш у , то код ASCII определяет закрепленный за ней символ. Поскольку за каждой клавишей закреплено , как правило , не менее двух символов ("а " и "А ", "1" и "!", "2" и "@" и т.д .), то каждому скэн-коду соотв етствуют , как минимум , два кода ASCII. В процессе трансл яции программа int09h анализирует состоян ие флагов , так что если нажата , например , клавиша Q (скэн-код 10h, код ASCII бу квы Q - 51h, а буквы q - 7lh), то формируетс я двухбайтовый код 1071h, но если клавиша Q нажата при нажатой клавише (смена регист ра ), то результат трансляции составит 1051h. Тот же код 1051h получится , ес ли при нажатии клавиши Q был включен режим (заглав ные буквы ), однако при включенном режиме и нажато й клавише образуется код 1071h, поскольку в такой ситуации клавиша на время нажатия переводит клавиатуру в режим нижнего регистре (строчн ые буквы ). Полученный в результате трансляции двухбайтовый код засылается программой int09h в кольцевой буфер ввода , который служит для синхронизации проце ссов в вода данных с клавиатуры и приема их выполняемой компьютером программой . Объем буфера составляет 16 слов , при этом к оды символов извлекаются из него в том же порядке , в каком они в него пост упали . За состоянием буфера следят два ука зателя . В хвостовом ука з ателе (сло во по адресу 40:lCh) хранится адрес первой свободной я чейки , в головном указателе (40: 1Ah) - адрес самого старого кода , принятого с клавиатуры и еще не востребованного программой . Оба адреса предс тавляют собой смещения относительно начала об ласт и данных BIOS, т.е . числа от 1Eh до 3Ch. В начале работы , ко гда буфер пуст , оба указателя - и хвостовой , и головной , указывают на первую ячейку буфера. Программа int09h, сформировав двухбайтовый код , помещает его в буфер по адресу , находящем уся в хвостовом указателе , после чего этот адрес увеличивается на 2, указывая опят ь на первую свободную ячейку. Каждое последующ ее нажатие на какую-либо клавишу добавляет в буфер очередной двухбайтовый код и с мещает хвостовой указатель. Выполняемая программа , желая получ ить код нажатой клавиши , должна обратиться для этого к каким-либо системным средствам - функциям ввода с клавиатуры DOS (прерывание 21h) или BIOS (прерывание 16h). Системные программы с помощью драйвера клавиатуры (точнее говоря , объединенного драйвера кла виатуры и экрана , так называемого драйвера консоли с именем CON) считывают из кольцевого буфера содержимое ячейки , адрес которой находится в головном указателе , и увеличивает этот адрес на 2. Таким образом , программный запрос на ввод с клавиатуры фактическ и выполняет прием кода не с клавиатуры , а из кольцевого буфера. Хвостовой указатель , перемещаясь по буфер у в процессе занесения в него кодов , д оходит , наконец , до конца буфера (адрес 40h:3Ch). В этом случае при поступлении очередного кода адр ес в указателе не увеличивается , а , н аоборот , уменьшается на длину буфера . Тем самым указатель возвращается в начало буфера , затем продолжает перемещаться по буферу до его конца , опять возвращается в начало и так далее по кольцу . Аналогичные ма нипуляции выполняются и с головным указателем. Равенство адресов в обоих указателях свидетельствует о том , что буфер пуст . Есл и при этом программа поставила запрос на ввод символа с клавиатуры , то драйвер консоли будет ждать поступления кода в буфер , после чего этот код будет перед ан в программу . Если же хвостовой указатель , перемещаясь по буферу в процессе его заполнения , подошел к головному указате лю "с обратной стороны " (это произойдет , есл и оператор нажимает на клавиши , а выполняе мая в настоящий момент программа не обращ ается к клавиатуре ), прием новых ко дов блокируется , а нажатие на клавиши возб уждает предупреждающие звуковые сигналы. Если ком пьютер не выполняет никакой программы , то активной является программа командного процессор а COMMAND.COM. Акти вность COMMAND.COM заключаетс я в том , что он , поставив запрос к DOS на ввод с клавиатуры (с помощью функции 0Ah прерывания 21h) ожидает ввода с клавиатуры очере дной команды пользователя . Как только в ко льцевом буфере ввода появляется код символа , функция 0Ah переносит его во внутренни й буфер DOS, очищая при этом кольцевой буфер ввода , а также выводит символ на экран . При п олучении кода клавиши (0Dh) функция 0Ah завершает свою рабо ту , а командный процессор предполагает , что ввод команды закончен , анализирует содержимое буфера DO S и приступает к выполнению введенн ой команды . При этом командный процессор р аботает практически лишь с младшими половинам и двухбайтовых кодов символов , именно , с к одами ASCII. Если компьютер выполняет какую-либо прогр амму , ведущую диалог с оператором , то , как ухе отмечалось , ввод данных с клави атуры (а точнее из кольцевого буфера ввода ) и вывод их на экран с целью эхо контроля организует эта программа , обращаясь непосредственно к драйверу BIOS (int 16h) или к соответствующе й функции DOS (int 21h). Может с лучиться , однако , что выпол няемой программе не требуется ввод с клав иатуры , а оператор нажал какие-то клавиши . В этом случае вводимые символы накапливаются (с помощью программы int09h) в кольцевом буфере ввода и , естественно , не отображаются на экране . Так можно ввести до 15 символов . Когда программа завершится , управление будет перед ано COMMAND. СОМ , который сразу же обнаружит наличие симво лов в кольцевом буфере , извлечет их оттуда и отобразит на экране . Такой ввод с клавиатуры называют вводом с упреждение м. До сих пор речь шла о символах и кодах ASCII, которым соответствуют определенные клавиши терминала и которые можно отобразить на экране . Это буквы (прописные и строчные ), цифры , знаки препинания и специальные знак и , используемые в программах и командных строках , например , |, $, * и др . Однако име ется ряд клавиш , которым не назначены отоб ражаемые на экране символы . Это , например , функциональные клавиши , ...; клавиши управления курсором , , , , <Стре лка вправо >, <Стрелк а вниз > и др . При нажатии этих клавиш в кольцевой буфер ввода засылается расширенный код ASCII, в котором младший байт равен нулю , а старший явля ется скэн-кодом нажатой клавиши . Расширенный к оды ASCII по ступают в буфер ввода и в случае нажа тия комбинаций у правляющих и функциональн ых клавиш , например, /, / (на дополнительной цифровой клавиатуре ), / и др . В этом случае , однако , в старший байт расширенного кода ASCII помещается уж е не скэн-код клавиши , а некоторый ко д , специально назначенный этой комбинации клавиш . Естественно , этого кода нет среди "обычных " скэн-кодов . Например , клавиша , скэн-код которой равен 3Bh, может генерировать следующие расширенные коды ASCII: З B00h / 5E00h / 6800h / 5400h Итак , прерывание , возникаю щее при нажатии или отпускании любой клав иши , обрабатывается по относительно сложному алгоритму с системным обработчиком , содержащимся в BIOS. Р ассмотрим примеры вмешательства в этот процес с . Ниже приведен пример прикладной прогр аммы , выполняющей некоторую обработку поступающих с клавиатуры данных еще до активизации системного обработчика. 3 . Описание программы 3.1. Описание для пользователя Приведённая ниже программа осуществляет перехват п рерыван ия от клавиатуры , и производит запись скэн -кодов клавиш и байта флагов клавиатуры в файл с именем « s_code&f.txt » . При этом фи ксируются только нажатия клавиш . Запись происходит при кажд ом шестнадцатом нажатии клавиши . Это сделано , во-первых , для ум еньшения вероятности потери «ценных» нажатий при экстренном вык лючении компьютера , во-вторых , для экономии опе ративной памяти , в-третьих , для сохранения норм альной работоспособности компьютера . Файл « s_code&f.txt » создаётся в родитель с ком каталоге программы . Если при инсталляции фа йл уже существует , то программа , автоматически , запишет в конец текущую дату и время , после этого будет осуществляться запись скэн-кодов и флагов в обычном режиме после даты и времени . Программа является рези д ентной . После того как она бу дет успешно инсталлирована , на экране появитс я соответствующая надпись “ Program installed”. В ней предус мотрена защита от повторной установки . Таким образом одновременно в оперативной памяти компьютера не может находится больше одной копии программы , что практически сводит к нулю шансы не корректной работы . Пр и попытке запустить программу после того как она уже была инсталлирована , на экране появится соответствующая надпись “ Program already installed”. Также эту программу можн о выгрузить из оперативной памяти после того как потребно сть в ней отпадёт . Для этого следует з апустить программу с ключом “ off” , т.е . в командной строке написать < имя программы > off . После этого вы увидите строку “ Program is DIE” , сигнализирующую об у спешной выг рузке программы . При этом содержимое буфера будет записано в файл . Таким образом , в файл будут записаны все нажатия клавиш вплоть до выгрузки программы . Если данную программу записать , например , в autoexec.bat, то можно будет проследить время на чала работы пользователя и какие кнопки он после этог о нажимал . Данная программа работает т олько в среде MS-DOS. 3 .2 Описание для программиста Программа пишетс я в формате СОМ , поэтому в ней предусм атри вается только один сегмент , с котором связываются сегментные ре гистры CS и DS; в начале сегмента резервируется 256 байт дня PSP. Инициализа ция. При запуске программы с кл авиатуры управление передается (в со ответствии с параметром директивы end) на начало процедуры main . Командой jmp сразу же осуществляе тся переход на секцию иници ализа ции , которая оформлена в виде отдельной процедуры . В секции инициализации подготавливаются условия для работы программы уже в ре зидентном состоянии. В начальной части инициализаци и мы проверяем наличие хвоста в PSP , если ж е в командной строке кроме имени команды ничего не было – переходим на дальнейший анализ : mov cl,es:80h cmp cl,0 je live Если хво ст присутствует , проверим не был ли введён ожидаемый параметр “ off” . При положительном результат е проверки устанавливаем флаг т ребования выгрузки “ flag” в единицу и переходим на даль нейший анализ. Затем вы зываем мультиплицированное прерывание int2Fh c функцией F1h и подфункцией проверки на повторную установку 00h . Если наш обработчик находится в оперативной памяти – он в озвратит AL = FFH, и прог рамма перейдёт на метку installed. Проверим установлен ли флаг требования выгрузки “ flag” . Если flag =1 перейдём на метку unins, где перешлём в первую (резидентну ю ) копию программы запрос на выгрузку из оперативной памяти по средствам прер ывания int2Fh и функцией F2h с подфункцией 01h . После чего происходит вывод ст роки “ Program is DIE” на экран сигнализирующей об успешном удалении резидентной части программы . После ч его выйдем из программы , обычным образом , функцией 4С 00h. Если фла г требо вания выгрузки “ flag” = 0, э то говорит о том , что введена неизвестная команда , а наш резидент уже инсталлирован . В этом случае выведем на экран предупреждающую надпись о невозможности повторной установки программы “ Program already installed” сопровождаемую з вуковым сигналом . После э того завершим программу функцией 4Ch с кодом возв рата 01 h . Если после прерывания int2Fh c функцией F200h , возвратиться AL FFh , т о нашего обработчика в памяти не оказалос ь . Сохраним смещения и сегменты системны х обработчиков int09h и int2Fh , а затем заполним векторы смещениями наших обработчиков. mov ax,352fh int 21h mov word ptr cs:old_2fh,bx mov word ptr cs:old_2fh+2,es mov ax,252fh mov dx,offset new_2fh int 21h mov ax,3509h int 21h mov word ptr cs:old_09h,bx mov word ptr cs:old_09h+2,es mov ax,2509h mov dx,offset new_09h int 21h После этого произведём поиск рабочего файла « s_code&f.txt» в текущем каталоге . Если файл не будет найден , то запустится про цедура div_f, которая создаст рабо чий файл и запишет в него строку « Skencode&Klav_flag file» . В дальнейшем в этот файл будут записыватьс я скэн-коды и байт флагов клавиатуры . Если файл уже существует , будет вызвана процед ура div2_f, которая допишет в конец файла текущ ую дату и время . Вывед ем на экран строку « Program installed» подтверждающую установку программы . Последн ими строками этой части инициализации вызывае тся функция DOS 31h, которая выполняет завершение програм мы с оставлением в памяти указанной ее ча сти . Размер резидентной части программы ( в параграфах ) передается DOS в регистре DX. Размер резидентн ой секции определяется разностью смещений end_res-main, которая равна длине резидентной части программы в байтах , прибавляется размер PSP (l00h) и еще число 15 (Fh) для того , чтобы посл е целочисленного деле ния на 16 результат был округлен в большую сторону. mov ax,3100h mov dx,(end_res-main+10fh)/16 int 21h С целью экон омии памяти секция инициализации располагается я конце программы и отбрасывается при ее завершении. Функция 31h, закрепи в за резидентной программой необходимую для ее функционирования память , передает управление командному процессору и вычислительная система переходит в исходное состояние . Наличие программы , резидентной в памяти , никак не отражается на хо да выч ислительног о процесса , за исключением того , что уменьшается объем свободной памят и . Одновременно в память может быть загруж е но любое число резидентных программ. Резидентна я часть обработчика. Эта секция программы имеет две точки входа : 1. Перехват прерывания int09h( клавиат ура ). В результате нажатия или отпускания клавиши на клавиатуре запускается процедура new_09h. 2. Перехват мультиплексо рного прерывания int2Fh . В результате перехвата мультиплексор ного прерывания запускается процедура new_2fh. Обработчик прерывания от клавиатуры. После запуска процедуры new_09h сохраним используемые ре гистры . Затем получим скэн-код последней нажатой клавиши . В противном случае восстановим регистры и пе редадим управление следующему по цепочке обра ботчику клавиатуры (скорее всего это буд ет BIOS -овски й обработчик « int09h » ). in al,60h cmp al,80h j a exit Затем за пишем этот скэн-код в буфер , считаем байт флагов клавиатуры из области данных BIOS и также занесём в буфер. Наш буфер имеет объём 32 байта , поэто му после каждого шестн адцатого нажатия необходимо сохранять буфер в рабочем файле . Для подсчёта нажатий введена переменная-счёт чик sch. Увеличим счётчик на 2, затем проверим п олон ли буфер , сравнив счётчик с 32. Если буфер не полон , сохраним использовавшиеся р егистры и передад им управление следующему по цепочке обработчику клавиатуры . Если б уфер забит , передадим управление процедуре fil . Эта процедура откроет наш рабочий фай л , установит указатель в конец и допишет столько байт из буфера начиная сначала , сколько укажет ей переме нная-счётчик. mov ah,40h mov cl,sch mov dx,offset bufer int 21h Это сделано для того , чтобы при удалении программы из памяти в файл были записаны все скэн-коды включая команду на удаление . Этот случай рассмотрим ниже . По сле того как данные будут сохранены , восстановим использовавшиеся регистры и передади м управление следующему по цепочке обработчик у клавиатуры . Обработчик мультип лексорного прерывания Процедура new_2fh пере хватит прерывание 2Fh , и если прерывание вызвано вместе с фун кцией F1h , то в зависимости от подфунк ции значение которой находится в AL выполнит следу ющие действия : 1. Если подфункция н аходящаяся в AL=00h (код наличия в памяти нашег о обработчика ), то наш обработчик возвратит в AL=FFh и выйдет из прерывания. cmp al, 00h je inst … inst: mov al,0ffh iret 2. Если подфункция н аходящаяся в AL=01h (команда на удаление из памяти обработчика ), то сохраним используемые регистры , вызовем процедуру fil (работа этой процедуры была описана выше ), а затем освободим блоки памяти занятые нашим обработчиком , восста новим старые векторы 09 h и 2 Fh . Восстановим использовавшиеся регистры и выйдем из прерывания. Если мул ьтиплексорное прерывание было вызвано с друго й функцией либо с нашей функцией но с другими подфункциями , то обраб отчик п ередаст управление следующему по цепочке обра ботчику мультиплексорного прерывания. cmp ah,0f1h jne out_2fh cmp al,00h je inst cmp al,01h je off jmp short out_2fh inst: mov al,0ffh iret out_2fh: 3 .3. Листинг программы text segment 'code' assume cs:text,ds:text org 256 main proc jmp init ; Поля данных резидентной секции old_2fh dd 0 ; Ячейка для сохранения системного вектора 2 Fh old_09h dd 0 ; Ячейка для со хранения систе много вектора 09 h bufer db 34 dup(?) ; Буфер для скэн-кодов и флагов клавиатуры sch db 0 ; Счётчик нажатий клавиш filename db 's_code&f.txt',0 ; Константа содержащая имя файла с которым работает программа ; Обработчик от клавиатур ы new_09h proc ; Сохраним используемые регистры push ax push bx push cx push dx push ds push cs ; Настроим DS на наш сегмент для простоты программирования pop ds in al,60h ; П олучим скэ н-код клавиши cmp al,80h ; Проверим , является ли скэн-код ко дом нажатия j a exit ; Нет – на выход mov bh,0 ; 0 BH mov bl,sch ; Текущее значения счётчика в BL mov [bufer+bx],al ; Запише м в буфер скэн-код клавиши inc bl ; Увеличим смещение буфера push es ; Сохраним регистр ES mov ax,40h ; Настроим ES на начало области данных BIOS mov es,ax mov al,es:[17h] ; Занесём байт флагов клавиатуры в AL pop es ; Восстановим ES mov [bufer+bx],al ; Запишем байт флагов в буфер inc bl ; Увеличим смещение на 1 add sch,2 ; Счётчик нажатий +2 cmp sch,32 ; Пора скидывать буфер в файл ? je go ; Да – на процедуру записи в файл jmp exit ; Н ет – на выход go: call fil ; Вы зов процедуры записи в файл ; Восстанов им использовавшиеся регистры exit: pop ds pop dx pop cx pop bx pop ax jmp cs:old_09h ; Передадим упра вление системном у обработчику “ int09h” new_09h endp ; Конец процедуры обработчика от к лавиатуры ; Процедура записи в файл скэн-кодов и флагов клавиатуры fil proc push cs ; Настроим DS на наш сегмент pop ds mov ah,3dh ; Функция от крытия файла mov al,1 ; для записи mov dx,offset filename ; DS:DX ASCIIZ имени файла int 21h mov bx,ax ; Дескриптор в ВХ xor cx,cx ; Отчистим СХ xor dx,dx ; и DX mov a x,4202h ; Функция установки указателя в конец файла int 21h mov ah,40h ; Функция записи в файл mov cl,sch ; CL количество байт mov dx,offset bufer ; DS:DX адрес буфера int 21h mov ah,3eh ; Функция закрытия файла int 21h mov sch,0 ; Обнулим счётчик ret ; Выход из процедуры fil endp ; Конец процедуры записи в файл ; Обработчик мультиплексорного прерывания new_2fh proc cmp ah,0f1h ; Проверим номер функции мультиплексо рного прерывания jne out_2fh ; Не наша – на выход cmp al,00h ; Подфункция проверки на повторную установку ? je inst ; Да , сообщим о невозможности пов торной установки cm p al,01h ; Подфункция выгрузки ? je off ; Да – на выгрузку jmp short out_2fh ; Неизвестная подфункция , на выход inst: mov al,0ffh ; Пр ограмма уже установлена iret ; Вы ход из прерывания out_2fh: jmp cs:old_2fh ; Перехо д в следующий по цепочке обработчик прерывания 2Fh ; Выгрузим программу из памяти , предварит ельно восстановив все перехваченные ею вектор ы ; Сохраним используемые регистры off: push ds push es push dx push ax push bx push cx call fil ; Вызов процедуры записи в файл содержимого буфера ; Восстановим использовавшиеся регистры pop cx pop bx pop ax ; Восстановим вектор 09h mov ax,2509h ; Функция установки вектора lds dx,cs:old_09h ; Заполним DS:DX int 21h ; Восстановим вектор 2fh mov ax,252fh ; Функция установки вектора lds dx,cs:old_2fh ; Заполним DS:DX int 21h ; Получим из PSP адрес собственного окружения и выгрузим его mov es,cs:2ch ; ES окружение mov ah,49h ; Функция освобождения блока памяти int 21h ; Выгрузим теперь саму программу push cs ; Загрузим в ES содержимое CS, т.е . сег ментный адрес PSP pop es mov ah,49h ; Функция освобождения блока памяти int 21h ; Восстановим использовавшиеся регистры pop dx pop es pop ds iret ; Возврат в вызвавшую программу new_2fh endp ; Конец процедуры обработки прерывани я 2 Fh end_res=$ ; Смещение конца резидентной части программы main endp tail db 'off' ; Ожидаемый хвост команды flag db 0 ; Флаг требования выгрузки tabl db '0123456789' ; Таблица для перевода BCD кода в ASCII time db 25 dup(?) ; Ячейка для сохранения те кущ ей даты и времени ; Процедура создания файла div_f proc mov ah,3ch ; Функция создания файла mov cx,0 ; Без атрибутов lea dx,filename ; DS:DX ASCIIZ имени файла int 21h mov bx,ax ; Дескриптор в ВХ mov ah,40h ; Функция записи в файл mov cx,buflen ; CХ количество байт lea dx,buf ; DS:DX адрес строки int 21h mov ah,3eh ; Функция закры тия файла int 21h ret ; Выход из процедуры div_f endp ; Конец процедуры создания файла ; Процедура открытия файла и записи в него текущей даты и времени div2_f proc mov [time],0ah ; Запись в переменную time маркеров mov [time+1],0dh ; перехода на следующую стро ку mov ah,3dh ; Функция открытия файла mov al,1 ; для записи mov dx,offset filename ; DS:DX ASCIIZ имени файла int 21h mov bx,ax ; Дескрипто р в ВХ push bx ; Сохраним дескриптор xor cx,cx ; Отчистим СХ xor dx,dx ; и DX mov ax,4202h ; Функция установки указат еля в конец файла int 21h mov ah,02h ; Функция чтения времени из «пост оянных» « CMOS » ча сов реального времени int 1ah ; Прерывание ввода – вывода для времени mov bx,offset tabl ; DS:DX адрес таблицы mov si,2 ; Установим смещение для переменной time mov ax,cx ; Часы и минуты со храним в AX mov cx,12 ; Установим счётчик сдвига next: push ax ; Со храним AX shr ax,cl ; Сдвинем AX на CL and al,0fh ; Получим номер ячейки в таблице прибавив м аску xlat ; Получим ASCII код числа mov [time +si],al ; Занесём его в переменную time inc si ; Увеличим на 1 смещение cmp si,4 ; Смещение = 4 ? je ras ; Да , переход на метку ras vw: sub cl,4 ; Не т , уменьшим CL на 4 pop ax ; Во сстановим AX cmp cl,-4 ; Сравним CL с -4 jne next ; Не равно – выполним ещё ра з jmp ent1 ; Равно – переход на ent1 ras: mov [time+si],':' ; З апишем в переменную time – « :» inc si ; Увеличим н а 1 смещение jmp vw ; Перейдём на метку vw ent1: mov [time+si],' ' ; З апишем в переменную time – « » inc si ; Увеличим н а 1 смещение mov ah,04h ; Функция чтения даты из «постоян ных» « CMOS » часов реального времени int 1ah ; Прерывание ввода – вывода для времени m ov ax,dx ; Дату сохраним в AX mov cx,12 ; Установим счётчик сдвига next1: push ax ; Со храним AX shr ax,cl ; С двинем AX на CL and al,0fh ; Получим номер ячейки в таблице прибавив маску xlat ; Получим ASCII код числа mov [time+si],al ; Занесём его в переменную time inc si ; Увеличим на 1 смещение cmp si,10 ; Смещение = 10 ? je ras1 ; Да , переход на метку ras1 vw1: sub cl,4 ; Не т , уменьшим CL на 4 pop ax ; Во сстановим A X cmp cl,-4 ; Сравним CL с -4 jne next1 ; Не равно – выполним ещё р аз jmp ent2 ; Равно – переход на ent2 ras1: mov [time+si],'.' ; З апишем в переменную time – «.» inc si ; Увеличим н а 1 смещение jmp vw1 ; Пе рейдём на метку vw1 ent2: mov [time+si],0ah ; З апись в переменную time маркеров mov [time+si+1],0dh ; п ерехода на следующую строку pop bx ; Восстановим дескриптор mov ah,40h ; Функция записи в файл mov c x ,20 ; CХ количество байт mov dx,offset time ; DS:DX адрес строки int 21h mov ah,3eh ; Функция закрытия файла int 21h ret ; Выход из процедуры div2_f endp ; Коне ц проце дуры подготовки файла ; Процедура инициализации init proc mov cl,es:80h ; Получим длину хвоста PSP cmp cl,0 ; Длина хвоста = 0 ? je live ; Да программа запущена без парам етров xor ch,ch ; Теперь CX=CL= длина хвоста mov di,81h ; DS:SI хвост в PSP lea si,tail ; DS:SI поле tail mov al,' ' ; Уберём пробелы из начала хвост а repe scasb ; Сканируем хвост , пока пробелы dec di ; D I первый симво л после пробелов mov cx,3 ; Ожидаемая длина параметра repe cmpsb ; Сравниваем введённый хвост с ож идаемым jne live ; Введена неизвестная команда inc flag ; Введено « off » , устано вим флаг запро са на выгрузку ; Проверим , не установлена ли уже дан ная программа live: mov ah,0f1h ; Установим нашу функцию mov al,0 ; и подфункцию на наличие нашей программы в оперативной памяти int 2fh cmp al,0ffh ; Программа у становлена ? je installed ; Да , при наличии запроса на в ыгрузку её можно выгрузить ; Сохраним вектор 2fh mov ax,352fh ; Функция получения вектора 2fh int 21h mov word ptr cs:old_2fh,bx ; Сохраним смещение системного обр аботчи ка mov word ptr cs:old_2fh+2,es ; Сохраним сегмент системного обр аботчика ; Заполним вектор 2fh mov ax,252fh ; Функция установления вектора преры вания 2fh mov dx,offset new_2fh ; Смещение нашего обработчика int 21h ; Сохраним вектор 09h mov ax,3509h ; Функция получения вектора 09h int 21h mov word ptr cs:old_09h,bx ; Сохраним смещение системного обр аботчика mov word ptr cs:old_09h+2,es ; Сохраним сегмент системного обра ботчика ; Заполним вектор 09h mov ax,2509h ; Функция установления вектора преры вания 09h mov dx,offset new_09h ; Смещение нашего обработчика int 21h mov ah,4eh ; Функция поиска файла lea dx,filename ; DS:DX ASCIIZ им ени файла int 21h cmp ax,12h ; Файл не найден ? je creat ; Да , создадим файл call div2_f ; Нет , вызов процедуры открытия фа йла и записи в него текущей даты и времени jmp by ; Переход на метку by creat: call div_f ; Вызов процедуры создания файл а ; Выведем на экран информационное сообще ние by: mov ah,09h ; Функция вывода на экран lea dx,mes ; DS:DX адрес строки int 21h mov ax,3100h ; Функция «завершиться и ост а ться резидентным» mov dx,(end_res-main+10fh)/16 ; Размер в параграфах int 21h installed: cmp flag,1 ; Запрос на выгрузку установлен ? je unins ; Да , на выгрузку ; Выведем на экран информационное сообще ние mov ah,09h ; Функция вывода на экран lea dx,mes1 ; DS:DX адрес строки int 21h ; Выведем предупреждающий звуковой сигнал mov cx,5 ; Количество гудков mov ah,02h ; Функция вывода на экран l: mov dl,07h ; ASCII код зуммера int 21h loop l ; Повторим CX раз mov ax,4c01h ; Функция завершения с кодом возв рата int 21h unins: ; Перешлём в первую (резидентную ) копию программы запрос на выгрузку mov ax,0f101h ; На ша функция с подфункцией выгрузки int 2fh ; Мультиплексное прерывание ; Выведем на экран информационное сообще ние mov ah,09h ; Функция вывода на экран lea dx,mes2 ; DS:DX адрес строки int 21h mov ax,4c00h ; Функция завершения программы int 21h buf db 'Skencode&Klav_flag file',0ah,0dh buflen equ $-buf mes db 'Program installed$' mes1 db 'Program already instal l ed$' mes2 db 'Program is DIE$' init endp text ends end main 3 .4. Рекомендации по улучшению – Главным недостатком этой программы является неудобное визуальное восприятие записей в файле . Т.е . мы видим не ASCII - код который образовался в результате нажатия клавиш и , а так называемый скэн-код (номер клавиши ) и состояние байта флагов клавиатуры , в котором он находился при этом нажатии . При необходимости можно написат ь процедуру в нашем обработчике либо в виде отдельной программы , которая анализировала бы байт флагов и в зависимост и от этого подставляла ASCII - код соотве тствующий скэн-коду нажатой клавиши. – Вторым недостатком нашей программы является не всегда удобн ый механизм выгрузки программы из оперативной памяти . Можно предусмотреть выгрузку нашей программы специ альной не стандартной к омбинацией клавиш. – Третий существенный недостаток программы состоит в том , что наш обработчик не реагирует на сочетание клавиш Clrl+Alt+Del. Так как наш обработчик перехватывает прерывания от клавиатуры раньше чем системный обраб отчик “ int 09 h ” , то было бы целесообразно при этом сочетании сбрасывать содержимое буфера в файл , а затем передавать управление системн ому обработчику . – Можно предусмотреть запись в файл autoexec . bat либо config . sys строки с путём к нашему файлу , пр и з апуске программы с параметром вводимым с командной строки. – Можно предусмотреть коррекцию размеров буфера , а также задава ть имя рабочего файла с помощью всё т ех же параметров вводимых с командной стр оки. – В зависимости от того в каких целях применяе тся д анный обработчик , можно запретить нажатие как ой либо клавиши , комбинации клавиш или пос ледовательности. Данная программа является шаблоном для резидентных обработчиков прерываний , в частности обработчиков прерываний от клавиатуры , и является огро мным полем для творчества . 4. Список используемой литературы 1. П.И.Рудаков , К.Г.Финогенов «Программируем на языке ассемблер а IBM PC » , Обнин ск 1997г. 2. Зубков С.В . « Assembler для DOS , Windows и UNIX » , Москва 2000г. 3. Богумирский Б.С . «Руководство пользо вателя ПЭВМ» , Са нкт– Петербург 1994г.
1Архитектура и строительство
2Астрономия, авиация, космонавтика
 
3Безопасность жизнедеятельности
4Биология
 
5Военная кафедра, гражданская оборона
 
6География, экономическая география
7Геология и геодезия
8Государственное регулирование и налоги
 
9Естествознание
 
10Журналистика
 
11Законодательство и право
12Адвокатура
13Административное право
14Арбитражное процессуальное право
15Банковское право
16Государство и право
17Гражданское право и процесс
18Жилищное право
19Законодательство зарубежных стран
20Земельное право
21Конституционное право
22Конституционное право зарубежных стран
23Международное право
24Муниципальное право
25Налоговое право
26Римское право
27Семейное право
28Таможенное право
29Трудовое право
30Уголовное право и процесс
31Финансовое право
32Хозяйственное право
33Экологическое право
34Юриспруденция
 
35Иностранные языки
36Информатика, информационные технологии
37Базы данных
38Компьютерные сети
39Программирование
40Искусство и культура
41Краеведение
42Культурология
43Музыка
44История
45Биографии
46Историческая личность
47Литература
 
48Маркетинг и реклама
49Математика
50Медицина и здоровье
51Менеджмент
52Антикризисное управление
53Делопроизводство и документооборот
54Логистика
 
55Педагогика
56Политология
57Правоохранительные органы
58Криминалистика и криминология
59Прочее
60Психология
61Юридическая психология
 
62Радиоэлектроника
63Религия
 
64Сельское хозяйство и землепользование
65Социология
66Страхование
 
67Технологии
68Материаловедение
69Машиностроение
70Металлургия
71Транспорт
72Туризм
 
73Физика
74Физкультура и спорт
75Философия
 
76Химия
 
77Экология, охрана природы
78Экономика и финансы
79Анализ хозяйственной деятельности
80Банковское дело и кредитование
81Биржевое дело
82Бухгалтерский учет и аудит
83История экономических учений
84Международные отношения
85Предпринимательство, бизнес, микроэкономика
86Финансы
87Ценные бумаги и фондовый рынок
88Экономика предприятия
89Экономико-математическое моделирование
90Экономическая теория

 Анекдоты - это почти как рефераты, только короткие и смешные Следующий
Стою в пробке, смотрю из своей японской малолитражки на даму элегантного возраста в крузаке и думаю - здорово ездить на такой машине...А она тоже на меня смотрит. Наверное думает - здорово быть молодой.
Anekdot.ru

Узнайте стоимость курсовой, диплома, реферата на заказ.

Обратите внимание, реферат по программированию "Системы программирования и операционные системы", также как и все другие рефераты, курсовые, дипломные и другие работы вы можете скачать бесплатно.

Смотрите также:


Банк рефератов - РефератБанк.ру
© РефератБанк, 2002 - 2016
Рейтинг@Mail.ru