ВУЗ:
Составители:
12
Обработка прерываний. Существуют способы заставить МП прервать выполнение
текущей программы и перейти к выполнению некой специальной подпрограммы, которая
в данном случае называется подпрограммой обслуживания прерывания. После её
завершения МП возвращается к прерванной программе и продолжает её выполнение.
Можно говорить о наличии трёх видов прерываний:
• аппаратные (от внешних устройств);
• программные (например, командой INT, от слова interrupt - прерывание);
• внутренние (например, при ошибке деления на ноль).
Нас здесь будут интересовать только программные прерывания, хотя механизм
обработки во всех трёх случаях аналогичен. За каждым прерыванием закрепляется его
номер (например, 10h) в пределах 0…256 (или, что то же самое, 00h…FFh). В начальных
адресах оперативной памяти располагается особая структура данных, называемая
таблицей векторов прерываний (ТВП). Каждый вектор - это, по сути дела, полный адрес
начала подпрограммы обработки соответствующего прерывания, состоящий из адреса
сегмента (1 машинное слово) и смещения (ещё 1 машинное слово), занимающий 4 байта.
Вся ТВП, таким образом, занимает 256*4 = 1024 байта.
Получив какую-либо команду вызова прерывания (например, INT 10h), МП
сохраняет в стеке полный (CS, IP) адрес очередной команды в прерванной программе,
затем там же сохраняет регистр FLAGS, сбрасывает флаги IF и TF, после чего обращается
к ТВП и, основываясь на номере прерывания, извлекает из ТВП адрес подпрограммы
обработки. Далее МП выполняет эту подпрограмму (и тем самым обслуживает
прерывание), пока ему не встретится команда IRET (возврат из прерывания). По этой
команде МП восстанавливает из стека сохранённый ранее адрес (а также и регистр
FLAGS) и возвращается, таким образом, к продолжению прерванной программы.
Может возникнуть вопрос: в чём разница между обычным вызовом подпрограммы
(командой CALL) и вызовом подпрограммы через механизм прерываний (в частности,
командой INT)? При пользовании командой CALL программист обязан знать адрес
начала подпрограммы, в то время как при вызове прерывания знать этот адрес
совершенно не нужно - нужен лишь номер соответствующего прерывания. Это очень
удобно при вызове различных сервисов операционных систем (ОС). Ряд ОС, в том числе и
MS-DOS-подсистема ОС Windows, содержат в себе большое количество стандартных
подпрограмм обслуживания клавиатуры, мыши, дисплея, дисковых устройств, COM- и
LPT-портов и т.д. Так, указанный выше номер 10h применяется для обслуживания
дисплейной подсистемы.
Отметим ещё раз, что команды RET и IRET выполняют различные действия и не
являются взаимозаменяемыми.
Команды организации циклов. Хорошо известно, что без циклического
выполнения команд не обходится ни одна сколько-нибудь сложная программа. При
работе на Ассемблере можно организовать циклы, используя команды условных
переходов. Однако, кроме этого, 8086-совместимые МП предоставляют в распоряжение
программиста специальные команды циклов, в частности, LOOP, LOOPNZ, LOOPZ
(loop по-английски - петля). Все эти команды используют метку, расположенную выше по
программе (примеры будут даны ниже). Часть программы между меткой и какой-либо из
рассматриваемых команд и есть тело цикла. Перед входом в цикл следует записать в
регистр CX число повторений цикла (ситуация, аналогичная префиксам строковых
команд). Каждый раз при очередном повторении тела цикла МП будет автоматически
вычитать единицу их СХ. Цикл закончится, если:
• СХ будет равен 0 (для команды LOOP);
• СХ будет равен 0 или флаг ZF будет равен 1 (для команды LOOPNZ);
• СХ будет равен 0 или флаг ZF будет равен 0 (для команды LOOPZ).
12 Обработка прерываний. Существуют способы заставить МП прервать выполнение текущей программы и перейти к выполнению некой специальной подпрограммы, которая в данном случае называется подпрограммой обслуживания прерывания. После её завершения МП возвращается к прерванной программе и продолжает её выполнение. Можно говорить о наличии трёх видов прерываний: • аппаратные (от внешних устройств); • программные (например, командой INT, от слова interrupt - прерывание); • внутренние (например, при ошибке деления на ноль). Нас здесь будут интересовать только программные прерывания, хотя механизм обработки во всех трёх случаях аналогичен. За каждым прерыванием закрепляется его номер (например, 10h) в пределах 0…256 (или, что то же самое, 00h…FFh). В начальных адресах оперативной памяти располагается особая структура данных, называемая таблицей векторов прерываний (ТВП). Каждый вектор - это, по сути дела, полный адрес начала подпрограммы обработки соответствующего прерывания, состоящий из адреса сегмента (1 машинное слово) и смещения (ещё 1 машинное слово), занимающий 4 байта. Вся ТВП, таким образом, занимает 256*4 = 1024 байта. Получив какую-либо команду вызова прерывания (например, INT 10h), МП сохраняет в стеке полный (CS, IP) адрес очередной команды в прерванной программе, затем там же сохраняет регистр FLAGS, сбрасывает флаги IF и TF, после чего обращается к ТВП и, основываясь на номере прерывания, извлекает из ТВП адрес подпрограммы обработки. Далее МП выполняет эту подпрограмму (и тем самым обслуживает прерывание), пока ему не встретится команда IRET (возврат из прерывания). По этой команде МП восстанавливает из стека сохранённый ранее адрес (а также и регистр FLAGS) и возвращается, таким образом, к продолжению прерванной программы. Может возникнуть вопрос: в чём разница между обычным вызовом подпрограммы (командой CALL) и вызовом подпрограммы через механизм прерываний (в частности, командой INT)? При пользовании командой CALL программист обязан знать адрес начала подпрограммы, в то время как при вызове прерывания знать этот адрес совершенно не нужно - нужен лишь номер соответствующего прерывания. Это очень удобно при вызове различных сервисов операционных систем (ОС). Ряд ОС, в том числе и MS-DOS-подсистема ОС Windows, содержат в себе большое количество стандартных подпрограмм обслуживания клавиатуры, мыши, дисплея, дисковых устройств, COM- и LPT-портов и т.д. Так, указанный выше номер 10h применяется для обслуживания дисплейной подсистемы. Отметим ещё раз, что команды RET и IRET выполняют различные действия и не являются взаимозаменяемыми. Команды организации циклов. Хорошо известно, что без циклического выполнения команд не обходится ни одна сколько-нибудь сложная программа. При работе на Ассемблере можно организовать циклы, используя команды условных переходов. Однако, кроме этого, 8086-совместимые МП предоставляют в распоряжение программиста специальные команды циклов, в частности, LOOP, LOOPNZ, LOOPZ (loop по-английски - петля). Все эти команды используют метку, расположенную выше по программе (примеры будут даны ниже). Часть программы между меткой и какой-либо из рассматриваемых команд и есть тело цикла. Перед входом в цикл следует записать в регистр CX число повторений цикла (ситуация, аналогичная префиксам строковых команд). Каждый раз при очередном повторении тела цикла МП будет автоматически вычитать единицу их СХ. Цикл закончится, если: • СХ будет равен 0 (для команды LOOP); • СХ будет равен 0 или флаг ZF будет равен 1 (для команды LOOPNZ); • СХ будет равен 0 или флаг ZF будет равен 0 (для команды LOOPZ).
Страницы
- « первая
- ‹ предыдущая
- …
- 10
- 11
- 12
- 13
- 14
- …
- следующая ›
- последняя »