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

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

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

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

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

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

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

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

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

                                                                                                                                                                                                                                   

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

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

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

_______________

г. Одесса 2000 г.

Содержание:

1.<span Times New Roman"">     

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

2.<span Times New Roman"">     

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

2.1.<span Times New Roman"">  

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

2.2.<span Times New Roman"">  

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

2.3.<span Times New Roman"">  

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

2.4.<span Times New Roman"">  

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

2.5.<span Times New Roman"">  

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

2.6.<span Times New Roman"">  

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

2.7.<span Times New Roman"">  

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

3.<span Times New Roman"">     

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

3.1.<span Times New Roman"">  

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

3.2.<span Times New Roman"">  

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

3.3.<span Times New Roman"">  

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

3.4.<span Times New Roman"">  

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

4.<span Times New Roman"">     

Список используемойлитературы…………………………………………………………..….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

<span Arial",«sans-serif»;mso-bidi-font-family: «Times New Roman»">Рис

<span Arial",«sans-serif»;mso-bidi-font-family:«Times New Roman»; mso-ansi-language:EN-US"> 2<span Arial",«sans-serif»;mso-bidi-font-family:«Times New Roman»">.1. Типичнаяструктура резидентной программы.

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

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

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

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

<img src="/cache/referats/4064/image001.gif" v:shapes="_x0000_s1030 _x0000_s1032 _x0000_s1033 _x0000_s1036">


Точка входа  <span Times New Roman";mso-hansi-font-family: «Times New Roman»;mso-char-type:symbol;mso-symbol-font-family:Symbol">®

   main

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

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

                                      <span Times New Roman"; mso-hansi-font-family:«Times New Roman»;mso-ansi-language:EN-US;mso-char-type: symbol;mso-symbol-font-family:Symbol">:

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

<img src="/cache/referats/4064/image002.gif" v:shapes="_x0000_s1034">     Точка входа <span Times New Roman";mso-hansi-font-family: «Times New Roman»;mso-char-type:symbol;mso-symbol-font-family:Symbol">®

    entry                                     программы

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

                                      <span Times New Roman";mso-hansi-font-family:«Times New Roman»; mso-ansi-language:EN-US;mso-char-type:symbol;mso-symbol-font-family:Symbol">:

   коды

                                    iret

<img src="/cache/referats/4064/image002.gif" v:shapes="_x0000_s1035">                                     init

                            .   Секция

                                <span Times New Roman"; mso-hansi-font-family:«Times New Roman»;mso-ansi-language:EN-US;mso-char-type: symbol;mso-symbol-font-family:Symbol">:

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

                                ФункцияDOS 31h   <span Times New Roman"; mso-hansi-font-family:«Times New Roman»;mso-ansi-language:EN-US;mso-char-type: symbol;mso-symbol-font-family:Symbol">®

     с составлением в памяти   

<img src="/cache/referats/4064/image003.gif" v:shapes="_x0000_s1031">                                                                                            её резидентной части

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

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

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

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

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

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

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

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

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

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

      Наиболее распространенным методом защитырезидентной программы от повторной установки является использование прерывания 2Fh,специально предназначенного для связи с резидентнымипрограммами. При вызове этого прерывания в регистре АН задается номер функции(от 00h до FFh), а в регистреAL — номерподфункции (в том же диапазоне). 00h — 7Fhзарезервировано дляDOS/Windows 0B8h — 0BFhзарезервировано для сетевых функций 0C0h- 0FFhотводится для программ.

Длятого, чтобы резидентная программа могла отозваться на вызов прерыванияint2Fh, в ней должен иметься обработчик этогопрерывания. Фактически все резидентные программы, как системные, так иприкладные, имеют такие обработчики, через которые осуществляется не толькопроверка на повторную установку, но и вообще связь с резидентной программой:смена режима ее работы или получение от неё в транзитную программу каких-топараметров. Задание действия, которое надлежит выполнить обработчику прерывания2Fh конкретной резидентной программы, осуществляется с помощью номера подфункции,помещаемого перед вызовом прерывания в регистр AL

Такимобразом, обработчик прерывания 2Fh резидентной программы должен, прежде всего,проверить номер функции в регистре АН; при обнаружении «своей»функции обработчик анализирует содержимое регистра AL и выполняет затребованныедействия, после чего командой iretпередаступравление вызвавшей его программе. Если, однако, обработчик обнаружил врегистре АН «чужую» функцию, он должен командойjmp CS:old_2fhпередать управление по цепочкетому обработчику, адрес которого был ранее в векторе 2Fh. В результате вызовint 2Fh из любой программы будет проходить по цепочке через все загруженныерезидентные программы, пока не достигнет «своей» программы или невернет управление в вызвавшую программу через обработчикDOS (который, очевидно, всегда будет самым последним вцепочке).

Естественно,для коммуникации с резидентной программой должен быть установлен некоторыйинтерфейс. Обычно при проверке на повторную установку резидентная программа,если она уже находится в памяти, возвращает в регистре AL значение FFh, котороеявляется признаком запрета вторичной загрузки. Иногда для большей надежностиидентификации «своей» функции резидентная программа, помимо значенияFFh в регистре AL, возвращает еще какие-то обусловленные заранее коды в другихрегистрах. Часто через дополнительные регистры передастся символьнаяинформация, например, имя программы. В этом случае, если вызвавшая программа сименемDUMP.COM(т.е.вторая копия резидентной программы, выясняющая, можно ли ей остатьсярезидентной в памяти) получает после вызова int 2Fh в регистре AL значение FFh,а в регистрах СХ иDXсимвольныекоды'DU'и 'МР', она может бытьуверена, что ее первая копия уже находится в памяти.Если же в регистре AL вернулся код FFh, а в регистрах СХ иDX -коды, например, 'ОК' и'RB',это, скорее всего означает, что закрепленная за нашейпрограммой функция мультиплексного прерывания ухе используется другойрезидентной программой. В этом случае стоит сменить функцию, чтобы невозбуждать конфликтных ситуаций.

Врезидентную часть следует включить обработчик прерывания 2Fh. Его расположениев пределах текста программы не имеет особого значения; мы поместили его вначале резидентной части. Секция инициализации претерпела большие изменения.Она должна начинаться с вызова прерывания 2Fh с соответствующей функций дляпроверки на повторную установку. Если первая копия программы уже загружена,текущую программу следует завершить не функцией3th(завершить и оставить в памяти), а обычной функциейзавершения4Ch.Если женашей программы в памяти нет, то в секции инициализации, помимо заполнения ее«рабочего» вектора, в данном случае03h,следует также установить наш обработчик мультиплексного прерывания.

Средифункций мультиплексного прерывания, предназначенных для прикладных программ, мыпроизвольно выбрали для нашей программы функцию F1h, а для проверки на повторную установку подфункцию00h.Резидентный обработчик прерывания2Fh, включенный в нашу программу, проверяет номера функциии подфункции и при обнаружении каких-либо других кодов передает управлениеследующему обработчику этого прерывания. Если же вызвана функция F1hс подфункцией 00h, обработчик устанавливает врегистреAL значениеFFh(«я уже загружен») и возвращает управлениев вызвавшую программу командойiret.

Секцияинициализации начинается с проверки на повторную установку. После загрузки врегистр АН номера функции(F1h),а врегистр AL -номераподфункции (00h), вызывается прерывание 2Fh. После возврата из прерыванияанализируется содержимое регистра AL Если обработчик вернул значение FFh,программа должна завершиться без оставления в памяти. Эти действия выполняютсяпо меткеinstalled.Есливозвращено другое значение, инициализация продолжается (для надежности стоилопроверить, возвращен ли именно 0). Сохраняется старое содержимое вектора2Fh,устанавливается наш обработчик этого прерывания,после чего выполняются все действия по установке, предусмотренные в старомварианте программы динамического дампа. При переходе на меткуinstalledна экран выводится сообщение оневозможности повторной установки и выполняется функция завершения 4Сh с кодомвозврата 01h.Последнее,конечно, имеет символический характер, поскольку этот код в дальнейшем неанализируется.

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

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

программныхпродуктов имеют встроенные средства выгрузки. Обычно выгрузка резидентнойпрограммы осуществляется соответствующей ко­мандой, подаваемой с клавиатуры ивоспринимаемой резидентной программой. Для этого резидентная программа должнаперехватывать прерывания, поступающие с клавиатуры, и «вылавливать»команды вы­грузки. Другой, боже простой способ заключается в запуске некоторойпрограммы, которая с помощью, например, мультиплексного прерыва­ния2Fhпередает резидентной программе команду выгрузки. Чащевсего в качестве «выгружающей» используют саму резидентную про­грамму,точнее, ее вторую копию, которая, если ее запустить в опреде­ленном режиме, нетолько не пытается остаться в памяти, но, наоборот, выгружает из памяти своюпервую копию.

Выгрузкурезидентной программы из памяти можно осуществить разными способами. Наиболеепростой — освободить блоки памяти, за­нимаемые программой (собственнопрограммой и ее окружением) с помощью функцииDOS 49h.Другой, более сложный — использовать в выгружающей программефункцию завершения4Ch,заставивее завер­шить не саму выгружающую, а резидентную программу, да еще после этоговернуть управление в выгружающую. В любом случае перед осво­бождением памятинеобходимо восстановить все векторы прерываний, перехваченные резидентнойпрограммой. Следует подчеркнуть, что вос­становление векторов представляет вобщем случае значительную и иногда даже неразрешимую проблему. Во-первых,старое содержимое вектора, которое хранится где-то в полях данных резидентнойпрограм­мы, невозможно извлечь «снаружи», из другой программы, так какнет никаких способов определить, где именно его спрятала резидентная программав процессе инициализации. Поэтому выгрузку резидентной программы легчеосуществить из нее самой, чем из другой программы. Во-вторых, даже есливыгрузку осуществляет сама резидентная про­грамма, она может правильновосстановить старое содержимое вектора лишь в том случае, если этот вектор небыл позже перехвачен другой резидентной программой. Если же это произошло, втаблице векторов находится уже адрес не выгружаемой, а следующей резидентнойпро­граммы, и если восстановить старое содержимое вектора, эта следующаяпрограмма «повиснет», лишившись средств своего запуска. Поэтому на­дежноможно выгрузить только последнюю из загруженных резидент­ных программ.

Внашей программе подфункция00hпрерывания2Fh служит для проверки на повторную установку, а подфункция01h -для выгрузки. В секцию инициализации добавлены строкисохранения старого содержимого вектора09h.Это выполняется точно так же, как и для вектора 2Fh — с помощью функцииDOS 35h.Старый вектор сохра­няется вячейкеold_09h,размещаемой в резидентной части программы. Поскольку выгрузка программывыполняется с помощью прерывания 2Fh, текст обработчика этого прерыванияусложняется.

Резидентныйобработчик прерывания2Fhпреждевсего проверяет номер функции, поступивший в регистре АН, Если этот номер от­личаетсяотF1h,управление передаетсяследующему обработчику по цепочке. Далее анализируется содержимое регистраAL.ЕслиAL=00h, выполняютсядействия по защите от повторной загрузки. ЕслиAL=01h, осуществляется переход на меткуuninstallдля выполнения действий по выгрузке программы. При любомдругом номере подфункции управле­ние передается следующему обработчику поцепочке.

Пометкеuninstallосуществляется сохранение используемых далее регистров (что делается скорее длякрасоты, чем по необходимости) и функциейDOS 25hвосстанавливается из ячеекold_09hиold_2Fhис­ходноесодержимое соответствующих векторов. Далее из ячейки со сме­щением2Chотносительно началаPSPв регистрESзагружается адрес окружения программы. Сегментный адрес освобождаемого блокапамя­ти — единственный параметр, требуемый для выполнения функцииDOS 49h.Размер освобождаемого блокаDOSизвестен, он хранится в блоке управления памятью(МСВ). Далее освобождается блок памяти с самой программой. Сегментный адресэтого блока (адрес PSP) находится в регистреCS.Наконец, командойiretуправление передастся в програм­му, вызвавшую прерывание 2Fh.

Функция49hоповещаетDOSо том, чтоданный блок памяти сво­боден и может впредь использоватьсяDOS.Это, однако, не мешает вы­полняться завершающимстрокам программы (в данном случае –коман­деiret), поскольку освобождение памяти не разрушает ее содержимого. Нашарезидентная программа физически сотрется лишь после того, как в память будетзагружена очередная выполняемая программа.

Еслипрограмма запускается с клавиатуры с указанием каких-либо параметров (именфайлов, ключей, определяющих режим работы про­граммы и проч.), тоDOS,загрузив программу в память, помещает все символы,введенные после имени программы (так называемый хвост команды) в префикспрограммного сегмента программы, начиная с от­носительного адреса80h.Хвост команды помещается в PSP во вполне определенномформате. В байт по адресу 80hDOSзаносятчисло сим­волов в хвосте команды (включая пробел, разделяющий на команднойстроке саму команду и ее хвост). Далее (начиная с байта по адресу 81h) следуют все символы, введенные с клавиатуры донажатия клавиши .Завершается хвост колом возврата каретки (13).

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

Посколькудействия программы при её запуске зависят от того, вве­дена ли команда запускас параметром или нет, наличие хвоста вPSPанализируется в самом начале секции инициализации. При запуске программытипа СОМ все сегментные регистры указывают на начало PSP. Байт с длиной хвоста(возможно, нулевой) помещается в регистр CLи сравнивается с нулем. Если в нем 0, команда запуска былавведена без параметров и инициализация программы продолжается обычным образом.Если хвост имеет ненулевую длину, начинается его анализ.

Обнулениемрегистра СН длина хвоста «расширяется» на весь ре­гистр СХ, что нужнодля организации цикла. РегистрDIнастраивается на первый байт хвоста, а регистрSI –на начало поляtailсожидаемой формой параметра. РегистрALподготавливается для выполнения ко­манды сканирования строки. Командаscasbсравнивает в цикле байты хвоста с содержимым AL(кодом пробела). Сравнение ведется до тех пор, пока не будет найден первыйсимвол, отличный от пробела. Эта операция необходима из-за того, что операторпри вводе команды вы­грузки может отделить параметр команды от самой командылюбым числом пробелов, которые попадут в хвост команды в PSP и помешаютанализировать введенный параметр.

Выходиз цикла выполнения команды scasb осуществляется, когда командапроанализировала первый после пробела символ. После этого регистр DI указываетна второй символ параметра. КомандаdecDIкор­ректирует указатель DI, направляя его на первый значащий символ вве­денногопараметра. Далее командой сравнения строкcmpsbосу­ществляется сравнение трех оставшихся символов хвоста.Если символы совпадают с параметром  'off', записанным в программе, устанавливается флаг запросана выгрузку. Если результат сравнения оказался отрица­тельным, флаг запроса неустанавливается (и, следовательно, непра­вильный параметр просто невоспринимается). В любой случае осу­ществляется переход на продолжениепрограммы, начинающей прове­рять, не установлена ли уже эта программа в памяти.Если программа еще не установлена, введенный параметр не имеет смысла. Инициали­зацияосуществляется обычным образом: сохраняются и устанавливают­ся векторы ипрограмма завершается с оставлением в памяти.

Приналичии в памяти резидентной копии этой программы осу­ществляется переход наметкуinstalled,где преждевсего проверяется, установлен ли флаг запроса на выгрузку. Если флаг сброшен,выводится сообщение о невозможности повторной загрузки и программа завер­шаетсяс кодом возврата 1. Если флаг запроса установлен, выполняется выгрузкапрограммы, которая заключается в вызове мультиплексного прерывания2Fhс функциейF1hиподфункцией01h.Резидентный об­работчик этого прерывания, включенный в состав нашей резидентнойпрограммы, отработает эту подфункцию, восстановитвекторы и освободит занятые программой блоки памяти. После возврата управленияиз обработчика в текущую программу будет выведено сообщение об успешнойвыгрузке и программа будет завер­шена функцией4Chс нулевым кодом возврата.

Составленнаянами программа не избавлена от недостатков. Так, в ней анализируются всегдатолько 3 значащих символа хвоста. Таким об­разом, программа будет выгружена ипри вводекоманды (имя).com onset.Другойнедостаток заключается в том, что результат сравне­ния записанного в программехвоста с введенным с клавиатуры пара­метром будет положительным, только если склавиатуры введены строчные буквы. Команда(имя)OFFнеприведет к выгрузке про­граммы. По-настоящему следовало включить в программуперед анали­зом хвоста преобразование символов параметра в прописные буквы.

<span Times New Roman",«serif»;font-weight:normal">2.4.Перехват прерываний

   В архитектуре процессоров80х86 предусмотрены особые случаи, когда процессор прекращает(прерывает) выполнение текущей программы и немедленно передает управлениепрограмме-обработчику, специально написанной для обработки подобной ситуации.Такие особые ситуации делятся на два тина: прерывания и исключения, взависимости от того, вызвало ли эту ситуацию какое-нибудь внешнее устройствоили выполняемая процессором команда. Исключения делят­ся далее на три типа:ошибки, ловушки и остановы, в зависимости от того, когда по отношению квызвавшей их команде они происходят. Ошибки появляются перед выполнениемкоманды, поэтому обработчик такого исключения получит в качестве адресавозврата адрес ошибочной команды (начиная с процессоров80286). Ловушки происходят сразу после выполнения команды, так чтообработчик получает в качестве адреса возврата адрес следующей команды. Инаконец, остановы могут возникать в любой момент и вообще не предусматриватьсредств возврата управления в программу.

КомандаINT(а такжеINTOиINT3)используется в программах как раз для того, чтобы вызывать обработчикипрерываний (или исключений). Фактически они являются исключениями ловушки,поскольку адрес возврата, который передастся обработчику, указывает наследующую команду, но так как эти команды были введены до разделения особыхситуаций на прерывания и исключения, их практически всегда называют командамивызова прерываний. Ввиду того, что обработчики прерываний и исключений вDOSобычно не различают механизм вызова, с помощьюкомандыINT можно передавать управление,как на обработчики прерываний, так и исключений. Как показано в главе 4,программные прерывания, то есть передача управле­ния при помощи командыINT,являются основным средством вызова процедур DOSиBIOS,потому чтов отличие от вызова через командуCALLздесь ненужно знать адреса вызываемой процедуры — достаточно только номера. С другойсторо­ны интерфейса рассмотрим, как строится обработчик программногопрерывания.

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

Когдав реальном режиме выполняется команда INT, управление передается по адресу,который считывается из специального массива, таблицы векторов пре­рываний, начинающегосяв памяти по адресу0000h:0000h.Каждыйэлемент тако­го массива представляет собой дальний адрес обработчика прерыванияв форма­те сегмент: смещение или 4 нулевых байта, если обработчик не установлен.Команда INT помещает в стек регистр флагов и дальний адрес возврата, поэтому,чтобы завершить обработчик, надо выполнить командыpopfиretfили однуко­мандуiret,которая вреальном режиме полностью им аналогична.

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

Хотя прямое изменение таблицы векторов прерываний и кажетсядостаточно удобным, все-таки это не лучший подход к установке обработчикапрерывания, и пользоваться им следует только в исключительных случаях,например, внутри обработчиков прерываний. Для обычных программDOSпредоставляет две сис­темные функции:25hи35h -установитьи считать адрес обработчика прерыва­ния, которые и рекомендуются киспользованию в обычных условиях.

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

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

 Прерывания от внешнихустройств или аппаратные прерывания, — это то, что понимается под термином«прерывание». Внешние устройства (клавиатура, дисковод, таймер, звуковая картаи т. д.) подают сигнал, по которому процессор прерывает выполнение программы ипередает управление на обработчик прерывания. Всего на персональных компьютерахиспользуется 15 аппаратных прерываний, хотя теоретически возможностиархитектуры позволяют довести их число до 64.

–<span Times New Roman"">       

IRQ1(INT 9) — прерывание клавиатуры, вызывается при каждом нажатии и отпускании клавиши наклавиатуре. Стандартный обработчик этого преры­вания выполняет довольно многофункций, начиная с перезагрузки поCtrl-Alt-Delи заканчивая помещением кода клавиши в буфер клавиатурыBIOS.

 Самыеполезные для программ аппаратные прерывания — прерывания систем­ного таймера иклавиатуры. Так как стандартные обработчики этих прерываний выполняют множествофункций, от которых зависит работа системы, их нельзя заменять полностью.

прерванной программе. Эт

еще рефераты
Еще работы по программированию, базе данных