Goto... Search.. Hext Change.. Follou Previous 5 глава






Глава 3


Команды и алгоритмы



 


тельно треть этих программ написана в формате.COM (COMMAND.COM, FORMAT.COM; SYS.COM и др.), а две трети - в формате.EXE (FC.EXE, PRINT.EXE, XCOPY.EXE и т.д.). Ниже мы рассмотрим правила составле­ния и особенности исполнения как.ЕХЕ-, так и.СОМ-программ.

Другой критерий классификации программ определяет способ взаимо­действия прикладной программы с другими программам и самой DOS. По этому критерию программы делятся на два вида: транзитные и резидентные. Ход выполнения транзитной программы (а к транзитным относится подавляющее большинство приложений DOS) выглядит следующим об­разом. Пользователь запускает программу, вводя с клавиатуры ее имя, завершаемое нажатием клавиши Enter. Соответствующие программы-ком­поненты DOS отыскивают на диске файл с указанным именем, загружа­ют его в память и передают управление на входную точку этой программы. Далее программа выполняется, фактически монополизируя ресурсы ком­пьютера. Пока она на завершилась, пользователь не имеет доступа к DOS и, соответственно, лишен возможности запустить другую программу или выполнить какую-либо команду DOS. Ввод с клавиатуры возможен толь­ко в ответ на запрос текущей программы, если в ней предусмотрено обра­щение к клавиатуре за получением каких-либо данных.

Совсем по-другому функционирует резидентная программа. Пользо­ватель запускает се точно так же, как и транзитную, вводя с клавиатуры ее имя. Программы DOS загружают программный файл в память и переда­ют упраштенис на точку входа. Однако дальше вычислительный процесс развивается по-иному. Программа выполняет только свой начальный, инициализирующий фрагмент, после чего вызывает специальную функ­цию DOS (с номером 31h). Эта функция завершает программу и возвра­щает управление в DOS, но не освобождает память от завершившейся программы, а остаатяет эту программу в памяти, делая се резидентной. Программа остается в памяти и, можно сказать, ничего не делает. По­скольку управление передано DOS, пользователь может вводить с клави­атуры любые команды и, в частности, запускать другие транзитные (или резидентные) программы. Когда будет активизирована находящаяся в па­мяти резидентная программа' Как правило, резидентные программы вклю­чают в себя обработчики аппаратных или программных прерываний. Если, например, в резидентной программе имеется обработчик прерываний от системного таймера, который, как известно, выдает сигналы прерыва­ний приблизительно 18 раз в секунду, то каждое такое прерывание будет предавать управление резидентной программе, которая может, например, периодически выводить на экран текущее время или какую-то иную ин­формацию. Работа резидентной программы будет протекать независимо от других программ и параллельно с ними. Другим классическим примером резидентной программы является русификатор клавиатуры, который по­лучает управление при нажатии любой клавиши, независимо от того, какая программа сейчас выполняется. Задача русификатора — определить по имеющемуся в нем флагу, на каком языке работает пользователь, и в необходимых случаях сформировать соответствующий нажатой клавише код ASCII русской буквы.


Следует заметить, что необходимость в резидентных программах воз­никла лишь потому, что MS-DOS является существенно однозадачной системой. В многозадачной операционной системе Windows понятие рези­дентной программы в принципе отсутствует.

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

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

Программа типа.ЕХЕ

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

.586 code segment use 16 assume CS:code, main proc mov AX,data mov DS,AX mov AX,4COOh hit 2 111 main endp code ends data segment use!6 data ends stk segment stack db 256 dup(O) stk ends end main

разрешение трансляции всех;команд (386-486-Pentium);Начало сегмента команд; 16-разрядное приложение DS:data

; Начало главной процедуры Инициализация;сегментного регистра DS;Текст главной процедуры;Вызов функции DOS;завершения программы;Конец главной процедуры;Конец сегмента команд;Начато сегмента данных;Опрсдсления данных;Конец сегмента данных; Начало сегмента стека;Стек

;Консц сегмента стека;Консц программы и точка входа

Программа начинается с директивы ассемблера.586, разрешающей Использовать в тексте программы весь набор команд процессора Pentium (кроме привилегированных). Если программа будет использовать только базовый набор команд МП 86, указание этой директивы не обязательно.



Глава 3


Команды и алгоритмы



 


С другой стороны, ее указание не обязывает нас обязательно использо­вать команды Pentium. Если в программе предполагается использовать лишь дополнительные команды процессоров 486 или 386, то вместо.586 можно написать.486 или,386.

Указание любого номера 32-разрядного процессора приведет к тому, что по умолчанию программа будет транслироваться, как 32-разрядное приложение, в то время как нам нужно создать обычное 16-разрядное приложение. Для того, чтобы все адреса в программе рассматривались, как 16-битовые, необходимо придать сегментам команд и данных описа­тели use 16. Для сегмента стека этот описатель не нужен, так как в стеке

нет поименованных ячеек.

Программа состоит из трех сегментов — команд, данных и стека. Име­на сегментов выбраны произвольно. Собственно программа обычно со­стоит из процедур. Деление на процедуры не обязательно, но повышает ее наглядность и облегчает передачу управления на подпрограммы. В рассмат­риваемом примере сегмент команд содержит единственную процедуру main, открываемую оператором ргос (от procedure, процедура) и закрываемую оператором endp (end procedure, конец процедуры). Перед обоими опера­торами указывается имя процедуры, которое в дальнейшем может ис­пользоваться в качестве относительного адреса процедуры (в сущности, относительного адреса первого выполнимого предложения этой процеду­ры). У нас это имя выступает в качестве параметра завершающей програм­му директивы end. Имена процедур, так же, как и имена сегментов, выби­раются произвольно.

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

mov AX,data Инициализация

mov DS,AX;сегментного регистра DS;

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

Точно также обязательными являются и завершающие предложения

mov AX,4COOh lut 21h

;Вызов функции DOS;завершения программы

в которых вызывается функция DOS с номером 4Ch, Эта функция, как уже отмечалось, завершает программу, освобождает занимаемую ею па­мять и передает управление командному процессору COMMAND.COM. Еще два замечания следует сделать относительно процедуры трансля­ции и компоновки программы, Если сегмент данных расположить после сегмента команд, как это сделано в нашем примере, то у транслятора возникнут сложности при обработке встречающихся в программных пред-


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

С другой неприятностью мы столкнемся, если попытаемся включить в программу операции с 32-разрядными операндами (даже и с командами МП 86). Компоновщик TASM по умолчанию запрещает такого рода опе­рации. Чтобы преодолеть этот запрет, следует в команде вызова компо­новщика указать ключ /3.

Таким образом, приведенный в гл. 1 командный файл должен выгля­деть (для подготовки программы P.ASM) следующим образом:

tasm /z /zi /n /nil p,p,P tlink /x /v /3 p,p

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

Приведем в качестве еще одного примера простую законченную про-

. грамму типа.ЕХЕ, которая выясняет букву-обозначение текущего диска

!.и выводит ее на экран с поясняющей надписью.

;Пример 3-1. Получение текущего диска;Опишем сегмент команд assume CS:codc,DS:data code segment main ргос

AX,data;Настроим DS DS,AX;на сегмент данных mov AH,19h;Функция DOS получения int 2 Hi;текущсго диска add disk,AL Преобразуем номер в код ;ASCII mov AH,09h;Функция DOS вывода на; экран DX,offset rnsg;Адрес строки 21h; Вызов DOS АН,0 Hi;Функция DOS ввода символа 21h;Вызов DOS AX,4C001i;Функция DOS завершения 21h; программы

mov

mov hit mov int mov int code ends

mov


 

Глава з

;Опишем сегмент данных

data segment use 16

;Выводимый на экран текст Продолжение текста

msg db "Текущий диск "

disk db "A:",13,10,T

data ends

;Опишем сегмент стека

stk segment stack

:Стек

db 256 dup (0) stk ends

end main

Рассмотрим текст приведенного примера. После настройки сегмент­ного регистра DS на сегмент данных, вызывается функция DOS с номе­ром 19h, которая позволяет получить код текущего диска. У этой функции нет никаких параметров, а результат своей работы она возвращает в реги­стре AL в виде условного кода. О обозначает диск А:, 1 диск В:, 2 диск С: и т.д. Если, например, пользователь работает на диске F, то функция I9h вернет в AL код 5.

Для преобразования кода диска в его буквенное обозначение, мы вос­пользовались широко распространенным приемом. В полях данных опре­делена символьная строка, которая будет выводиться на экран. Для удоб­ства работы она разделена на две части, каждая из которых имеет свое имя. Началу строки присвоено имя msg, а той ее части, которая начинает­ся с обозначения диска А:, имя disk (разумеется, имена выбраны произ­вольно). Если посмотреть на таблицу кодов ASCII (рис. 3.1), то можно заметить, что код каждой следующей буквы ачфавита на 1 больше преды­дущей. Таким образом, если к коду латинской буквы A (41h) прибавить 1, получится код буквы В, а если прибавить, например, 5, получится код буквы F. Именно эта операция и выполняется в предложении

add disk,AL;Преобразусм номер в код ASCII

где к байту с адресом disk прибавляется код, возвращенный функцией DOS.

Выполнив модификацию строки, мы выводим се на экран уже знако­мой нам функцией DOS 09h. Она выводит все символы строки, пока не встретится с символом S, которым наша строка и завершается. Перед зна­ком S в строке имеются два числа: 13 и 10. При выводе текстовой строки на экран любой функцией DOS код 13 трактуется DOS, как команда вер­нуть курсор в начало строки («возврат каретки»), а код 10 —• как команда на перевод строки. Два эти кода переводят курсор в начало следующей строки экрана. В данном случае, когда на экран ничего больше не выво­дится, можно было обойтись и без этих кодов, которые включены лишь в познавательных целях.

Между прочим, правильная работа программы основана на том пред­положении (безусловно правильном), что ассемблер расположит наши данные в памяти в точности в том же порядке, как они описаны в про­грамме. Именно это обстоятельство и позволяет дробить единую строку на


 

анды и алгоритмы
АО ВО СО DO ЕО FO

00 01 02 03 04 05 06 07 08 09 OAOBOCODOEOF

0123456789:;< = >? 0ABCDEFGHIJKLMNO PQRSTUUWX¥Z[4]^_ abcdefghijklnno pqrstuvu х у 2: { I > ~ л

АБВГДЕЖЗИЙКЛМНОП РСТУФХЦЧЫЩЪЫЬЭЮЯ абагдемзий клмноп

h

_ л _ I? - II

II
лт
I I

Т

т « I t J

И Р с т

И Ф х цчыщъыьэ w я

«"-=-% ° • • -S № От

Рис. 3.1. Таблица кодов символов.

части, не опасаясь, что в память они попадут в разные места, что привело бы, разумеется, к непредсказуемому результату.

После вывода на экран сообщения о текущем диске в программе вы­зывается функция DOS с номером Olh. Эта функция вводит с клавиатуры один символ. Если символов нет (мы после запуска программы не нажи­мали на клавиши), функция Olh ждет нажатия фактически любой клави­ши (более точно — любой алфавитно-цифровой или функциональной кла­виши). Такой весьма распространенный прием позволяет остановить вы­полнение программы до нажатия клавиши, что даст возможность программисту посмотреть, что вывела программа на экран, и оценить правильность ее работы.

Наконец, последнее действие носит, как уже отмечалось, сакрамен­тальный характер. Вызовом функции DOS 4Ch программа завершается с передачей управления DOS.

Взглянем еще раз на текст программы 3-1. Если не считать первых предложений инициализации регистра DS, то в программе имеется лишь одна строка, носящая, можно сказать, вычислительный характер — это прибавление полученного кода диска к содержимому байта памяти. Все остальные строки служат для вызова тех или иных функций DOS — полу­чения информации о текущем диске, вывода строки на экран, остановки программы и, наконец, се завершения. Это подтверждает высказанное выше утверждение о важности изучения системных средств и широком использовании их в программах на языке ассемблера. Разумеется, в про­грамме могут быть и сколь угодно сложные и протяженные участки обра-



Глава 3


Команды и алгоритмы



 


 


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

Структура и образ памяти программы.СОМ

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

code segment;

assume CS:text,DS:text

org lOOh;Мссто для PSP main proc

;Текст программы main endp

;Определения данных code ends

end main.

Программа содержит единственный сегмент code. В операторе ASSUME указано, что сегментные регистры CS и DS будут указывать на этот един­ственный сегмент. Оператор ORG lOOli резервирует 256 байт для PSP. За­полнять PSP будет по-прежнему система, но место под него в начале сегмента должен отвести программист. В программе нет необходимости инициализировать сегментный регистр DS, поскольку его, как и осталь­ные сегментные регистры, инициализирует система. Данные можно раз­местить после программной процедуры (как это показано в приведенном примере), или внутри нее, или даже перед ней. Следует только иметь в виду, что при загрузке программы типа.СОМ регистр IP всегда инициа­лизируется числом lOOh, поэтому сразу вслед за оператором ORG lOOli должна стоять первая выполнимая команда программы. Если данные же­лательно расположить в начале программы, перед ними следует помес­тить оператор перехода на фактическую точку входа, например jmp entry.

Образ памяти программы типа.СОМ показан на рис. 3.2. После загруз­ки программы все сегментные регистры указывают на начало единствен­ного сегмента, т.е. фактически на начало PSP. Указатель стека автомати­чески инициализируется числом FFFEh. Таким образом, независимо от фактического размера программы, ей выделяется 64 Кбайт адресного про­странства, всю нижнюю часть которого занимает стек. Поскольку1 верхняя граница стека не определена и зависит от интенсивности и способа ис­пользования стека программой, следует опасаться затирания стеком ниж-


ней части программы. Впрочем, такая опасность существует и в програм­мах типа.ЕХЕ, так как в реальном режиме нет никаких механизмов защи­ты, и при сохранении в стеке большего объема данных, чем может так поместиться, данные начнут затирать поля того сегмента, который рас­положен над стеком, в наших примерах — сегмента данных.

CS.DS, ES, SS —>

Префикс программы (PSP) 256 байт

• = 010011

Программа и данные

Стек

<— SP = FFFEh

Рис. 3.2. Образ памяти программы.СОМ

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

data segment byte

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

Программа типа.СОМ состоит из единственного сегмента, и пробле­ма настройки ссылок не возникает. Файл с расширением.СОМ почти в точности отражает содержимое памяти после загрузки программы. Отли­чие заключается только в том, что в программном файле отсутствует пре­фикс программы PSP, который система вставляет в программу в процес­се ее загрузки. Таким образом, файл с расширением.СОМ обычно оказы­вается на 256 байт короче своего образа в памяти.

Если оттранслировать и скомпоновать программ}', написанную в фор­мате.СОМ, обычным образом, образуется программный файл с расши­рением.ЕХЕ. Этот файл можно запустить на выполнение, однако.рабо-тать он будет неверно. Дело в том, что система, загружая файл типа.ЕХЕ в память, пристраивает перед загруженной программой префикс и на­страивает на него регистры DS и ES. В результате значение DS окажется на 10h меньше, чем сегментный адрес сегмента с командами и данными,


. -Т" _Liaaa_j Команды и алгоритмы

что приведет к неправильной адресации при обращении к полям данных. Программ)1, написанную в формате.СОМ, можно запускать только в виде файла с расширением.СОМ, для которого в DOS предусмотрен свой алгоритм загрузки и запуска. Для того, чтобы компоновщик создал файл с расширением.СОМ, в строке запуска компоновщика необходимо пре­дусмотреть ключ /t (при использовании компоновщика TLINK.EXE):

tlink /х /v /3 /t p,p

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

Рассмотрим пример законченной программы типа.СОМ, которая выводит на экран строку текста.

; Место под PSP;Функция вывода на экран

;Пример 3-2. Простая.СОМ-программа assume CS:code,DS:code code segment

org 256 main proc

mov mov lilt mov int main endp, I msg db 16,16,16,'Программа типа.COM', 17,17,17,'$' code ends end main В начале программы отведено 256 байт под PSP; в программе отсут­ствует инициализация регистра DS; поле данных размещено в программ­ном сегменте непосредственно после последней команды. Для разнообра­зия в строку, выводимую на экран, включены коды 16 и 17, которые отображаются на экране в виде залитых треугольников (рис. 3.3). Как вид­но из этого рисунка, программа имела имя Р. СОМ и запускалась из ката­лога F:\CURRENT. Рассмотрим важный в принципиальном плане вопрос о месте разме­щения данных в.СОМ-программе. В нашем примере данные описаны в конце программного сегмента вслед за процедурой main, которая, как и в

AH,09h

DX,offsct msg

21h

;Функция завершения; про граммы

AX,4COOh

F:\CURREHT>p.com ^»Программа типа.СОИ 444

Рис. 3.3. Вывод программы 3-2.

21h


предыдущих примерах, введена скорее для порядка, чем по необходимо­сти. С таким же успехом можно было предложение с именем msg помес­тить после вызова int21h, внутри процедуры main. Третий возможный ва­риант, с которым мы еще столкнемся в примерах резидентных программ, приведен ниже.

assume CS:code,DS:code code segment

 

; Место под PSP

org main proc

jmp start;Первая выполнимая команда

msg db 16,16,16,"Программа типа.COM', 17,17,17,'$'
start: mov AH,09h;Функция вывода на экран

mov DX.offset msg

int 21h

;Продолжение программы

Таким образом, данные могут быть размещены как после программы, так И среди выполнимых предложений программы. Важно только соблюс­ти обязательное условие: ни при каких обстоятельствах на данные не дол­жно быть передано управление. В первом случае (пример 3-2) данные по­мещены за вызовом функции DOS, завершающей программу. Ясно, что после выполнения этой функции упраштение уже не вернется в нашу про­грамму, а будет передано командному процессору, поэтому размещение здесь данных вполне возможно. В последнем фрагменте данные описаны, можно сказать, в середине программы. Однако перед ними стоит команда безусловного перехода jmp, которая приводит при выполнении програм­мы к обходу данных.

А вот чего нельзя было сделать, так это разместить данные после зак­рытия сегмента, как это сделано в приведенном ниже (неправильном!) фрагменте:

main cndp;Конец процедуры

code ends;Конец сегмента

msg db 16,16,16,'Программа типа.СОМ', 17,17,17,'$' end main

Это второе обязательное условие: из чего бы ни состояла программа, все ее компоненты должны входить в те или иные сегменты. Вне сегментов допус­каются только нетранслируемые директивы ассемблера типа.586 или assume.

Наконец, третье условие, о котором уже говорилось, относится толь­ко к программам типа.COM. DOS, загрузив программу в память, иници­ализирует указатель команд числом lOOh, т.е. адресом первой команды вслед за оператором org lOOh. Поэтому главная процедура.СОМ-програм-мы (если в ней имеется несколько процедур) обязательно должна быть первой, причем первое предложение этой • процедуры должно быть вы­полнимой командой (например, командой jmp, как это показано выше).



Глава 3


Команды и алгоритмы



 


 


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

Обработчики прерываний являются важнейшей составной частью многих программных продуктов. Как было показано в гл. 1, прерывания разделяются на внутренние, возникающие в самом микропроцессоре в случае определенных сбоев (попытка деления на 0, несуществующая ко­манда), внешние, приходящие из периферийного оборудования (клавиа­тура, мышь, диски, нестандартные устройства, подключенные к компь­ютеру) и программные, являющиеся реакцией процессора на команду int с тем или иным номером. В прикладных программах приходится обрабаты­вать, главным образом, внешние и программные прерывания. Общие прин­ципы обслуживания тех и других прерываний одинаковы, однако условия функционирования обработчиков аппаратных прерываний имеют значи­тельную специфику, связанную, главным образом, с тем, что прерыва­ния от аппаратуры приходят в произвольные моменты времени и могут прервать текущую программу в любой ее точке. Обработчик прерывания должен быть написан таким образом, чтобы его выполнение ни в какой степени не отразилось на правильном функционировании текущей (пре­рываемой) программы.

Инициализация обработчика прерываний

Прерывание 1 Прерывание 2

Рассмотрим схематически структуру и функционирование программ­ного комплекса, включающего собственный обработчик какого-либо ап­паратного прерывания (рис. 3.4).

Дальнейший ход программы

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

Рис. 3.4. Функционирование программного комплекса с обработчиком прерываний.

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


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

Программа, начиная свою работу, прежде всего должна выполнить инициализирующие действия по установке обработчика прерываний. В простейшем случае эти действия заключаются в занесении в соответству­ющий вектор полного адреса (сегмента и смещения) обработчика. По­скольку обработчик входит в состав программы, его относительный адрес известен; это имя его процедуры или метка входной точки. Что же касает­ся сегментного адреса, то обработчик может входить в сегмент основной части программы, если она невелика по объему и занимает один сегмент, но может образовывать и самостоятельный сегмент. В любом случае в ка­честве сегментного адреса можно использовать имя соответствующего сегмента.

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

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

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

Рассмотрим структуру программы с обработкой аппаратных прерыва-шй. Наиболее удобным аппаратным прерыванием, которое можно ис-юльзовать в исследовательских целях, является прерывание от систем йо­та и мера, которое генерируется 18.2 раза в секунду и служит источни-)м сигналов для хода системных часов, отсчитывающих время, истекшее юсле включения машины. Замена системного обработчика на приклад-сой не приводит к каким-либо неприятностям, кроме, возможно, оста-совки на некоторое время системных часов.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: