В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 12
Текст из файла (страница 12)
)галсе ЦП продоккает свою работу (например, осуществляет следующую операцию обмена) или как-то реагирует на сбой в работе устройспа. Осуществлять подобным образом ввод-вывод в каждой программе - занятие трудоемкое. Оно требует знания многих технических деталей - номеров портов, управляющих сигналов и сипюлов опыта, порядка опроса портов н т. п., причем зта информаша различна для разных внешних устройсш.
А кроне того, в ккядой новой программе приходится заново описывать все действиа, сваэанные с вводом- выводом, что, конечно, накладно. В то же время в большинстве программ используются в общем-то одни и те же операции ввода-вывода. Учитывая все зто, поступают так: один раэ описмваютса часто используемые операции ввода-вывода, которые скрывают всю "кухню" работы с портаыи, н зти операции включают в состав операционной системы (ОС), постоянно находящейся в ОП, чтобы ими ыогла пользоваться любая программа, выполняемаа на ЭВМ. Такой способ существенно упрощает жизнь программистов, поэтому обычно используют только зти операции и не пользуются портами напрямшг. С портами работают лишь тогда, когда надо реализовать какой-нибудь необычный, зюотическитг ввод-вывод.
В связи с этим мы больше не будем говорить о машинных командах ввода-вывода и портах, а рассмотрим некоторые из операций ввгща-вывода, которые включены в состав ОС. Ввод-вывод. прерывания 232 13.2. Прерывания. Функции 1)ОЯ 13.2.1 Прерывання Одна из основных задач ОС - управление работой всех устройств, входящих в состав ЗВМ. Дпя выполнения этой задачи ОС обязана, в частности, оперативно следить за событиями, происходящими в устройствах. Пусть, к примеру, ЦП выполняет некоторую програьм»у и пусть в это время в каком-то внешнем устро»ктве произошло событие (например, на клавиатуре нажата клавиша), ма которое ОС должна прорвам»ровать (например, запомнить код нажатойг клавиши). Естественно, ждать пока закончится выполнение текущей программы нельзя, она может работать еще долго и за это время может быть мажато ммого друп»х клавиш, тах что информыпи о первой из нажатых клавиш будет потеряна.
Надо сразу, оперативно прореагировать на это событие. Кж это сделатьУ В современных ЭВМ эта проблема решается с помощью прерываний. Когда в некотором устройстве происходит событие, достойное внимания ОС, это устройство посылает в ЦП спепиапьный сигнал, мазываемый сигналом прерывания нли просто прерыванием.
Получив тжой сип»ал, ЦП прерывает свою обычную работу, т. е. выполнение команд текущей программы, и передает управление на ОС, которая определяет, кжое событие произошло, и соответствующим образом реагирует на него. Например, если прерывание пришло от клавиатуры в связи с тем, что была нажата некоторая клавиша, то ОС, считав из порта клавиатуры код этой клавиши, запоминает его где-то в своеы участке лазити. Когда ОС зжончит обработку прерывания, она заставляет ЦП возобновить выполнение прерванной программы с той команды, которую ЦП ранее должен был выполнить, но из-за поступившего прерывания не выполнил.
И вот тж ОС "вступает в игру" всякий раз, когда в устройствах ЗВМ возникаот те или иные события. Зто и позволяет ОС следить за всеми собьгпими в ЭВМ и оперативно реап»ровать на них. Уточним некоторые детали этой схемы на примере, ПК. Кж запоминается то место текущей программы, в котором было прервано ее выполнение? Напомним, что в.ПК адрес команды, которая должна быть выполнена следующей, находится в реп»страх Сб и 1Р. В момент прерывания эти регистры ипоказывюот на ту команду, которая была бм выполнена, если бы не было прерывамия, и с которой, следовательно, надо будет возобновить работу программы. (Отметим, что ЦП воспринимает сип»ал прерывания талы»о между командами, но не во время выполнения команды.) Поэтому, когда приходит сигнал прерывания, ЦП запоминает значения этих двух регистров, причем запоминает в стеке текущей программы: сначала в стек записывается содержимое СБ, а затем - 1Р.
(Замечание» ранее уже отмечалось, что если машинная программа сама не использует стек, то все равно под него надо отводить место в памяти; причина этого, кж видно, в том, что стек программы используется при прерываниях, которые происходят во время ее счета, например, из-за случайного нажатия клавиш на клавиатуре.) Помимо адреса следующей команды программы пропессор также запоминает в стеке и текущее значение флага репютров Р)аяв, т.
е. значения всех флагов. Зачемй Дело в том, что протрав»ь»а ьюжет быль прервана между командой "дмядопммэи 240 Пропэоммироэанио нв иэмко ассемблера ЩМ РС сравнения и следующей за ней командой условного перехода, и позже придется возобновлять работу программы с этой команды условного перехода Ясно, что в этот момент все флаги должны быть такими же, какими они были после команды сравнения, т. е. в моыент прерывания. Учитывая зто, ЦП и спасает регистр флагов, чтобы затем можно было его восстановить.
При этом регистр Р)аяз записывается в стек до адреса прерывания. Итак, когда в ЦП приходит сипгал прерывания, то он приостанавливает выпалнение текущей программы и спасает в стеке этой программы текущее значение флага регистров и адрес следующей команды, а затем уже передает управление на ОС. (Отметим, что ЦП также обнуляет флам прерывания 1Р и трассировки ТР.) Теперь уточним, как происходит передача управления на ОС.
Отметим, что ОС- это обмчная машинная программа, хотя и выполняющая некоторые специфические действия. Поэтому, чтобы застаюпь ее работать, надо передать управление на одну из ее коыанд. Но на какую именно? Ведь на разные прерывания надо реагировать по-разноыу, поэтому при разных прерывзниях надо передавазь управление на разные командм ОС. В ПК эта проблема решается следующим образом. Все возможные прерывания нумеруются числами от 0 до 255. )1ля каждого прерывания составляется свгм процедура обработки прерывания (ПОП), и все зти процедуры включаются в состав ОС.
Начальные адреса этих процедур записываются в самые первые ячейки памяти; зти адреса попадюот сюда при загрузке ОС в оперативную навить. При этом кюкдый такой адрес записывается в виде пары зея:о(з, где зея - номер сепаента памяти, в котором находится соответствующая ПОП, а о(з - ее смещение внутри этого сегмента.
В связи с этим каждый адрес занимает 4 байта, двойное слово, и потому начальный адрес 1-й ПОП располагается в двойном слове с адресом 4*1. Всего эти начальные адреса занимают 4"256м1024=1 Кб. Это место паьгяти принято называть вектором прерываний.
Таким образом, вектор прерываний - это массив из 256 элементов, 1-й элемент которого - начальный адрес процедуры обработки прерывания с номером г. Как используется вектор прерываний? Устройспю, в котором произошло событие, достойное внимания ОС, посылает в ЦП не только сигнал прерывания, но и номер этого прерывания (устройства, конечно, знают номера своих прерываний). Если это номер 1, тогда ЦП, сохранив в стеке регистр флагов и адрес прерывания, просто напросто передает управление по адресу из 1-го элемента вектора прерывания, делая тем самым переход на 1-ю ПОП, которая и начинает заниматься обработкой данного прерывания. ПОП - это в общем-то обмчнаа процедура. В частности, если она должна использовать какие-то регистры, то, как и все "порядочные" процедуры, она в начале своей работы спасает в стеке (прерванной программы или своем внутреннем) значениа этих регистров, а в конце работы восстанавливает их.
Поэтому, когда будет возобновлена работа прерванной прогрзммм, в регистрах останутся те же значения, которые были в них в момент прерывания. И, наконец, последнее уточнение. Когда ПОП закончит свою работу, она должна возобновить работу прерванной программм. Как это сделать? Очень просто: из стека надо считать три слова и восстановить по ним регистрм 1Р и СБ Ввод-вывод. Прерывания 241 (загрузка в этн регистры адреса н означает переход по этому адресу) н регнсгр флагов. Для осуществления этнх действнй в систему комюгд ПК введена команда "возврат нз прерывания" (1лгеппрг гепцп) без операндов: хает Ее действие: стек -> 1Р, стек -> СЗ, стек -> Р)айз. Этой комюшой процедуры обработки прерываний н завершают свою работу.
Итак, что пронзошло? Прежние значення всех репгстров сохранены, прежние состояния всех флагов восстановлены, управление передано на ту коыанду прерванной программы, которую ЦП нз-за прерывання не успел выполнить ранее. А это значит, что данная программа продолжит свою работу так, квк будто бы н не было прерывання. 13.2Л. Функццп ПОВ Рассмотренный механизм прерываний первоначально был предназначен для того, чтобы ОС ыогла следить за событиями во внешних устройствах ЭВМ (в прннтере, дисководах н др.). Но затем поняли, что этот механизм можно попользовать н в других целях.
Напрнмер, с его помощью ыожно реагировать на событии, происходящие в самом ЦП. Пусть, к примеру, прн выполнении какой-то программы встретилась команда деления на О. Ясно, что это ошибка н на нее надо как-то реапгровать. И делается это так: тот блок ЦП, который реализует операцню деления, обнаружнв, что делитель равен О, вырабатывает снпгал прермвання с определенным номером. Дальнейшие же событию, несмотря на то, что снгнал прерывання послал сам себе ЦП, ндуг по рассмотренной схеме, а потому вмзывается соответствующая ПОП нз ОС, которая выдает на экран сообщение об ошибке "деление на 0", прекращает выполненне программы н передает управление на ту часть ОС, которая осуществляет прием н выполнение приказов пользователя.
Другой случай, где полезно нсполыюванне прерываний, особенно интересен для нас сейчас. Давно уже замечено, что в разлнчных программах приходится выполнять одни н те же действия, например, выводить снмволы на экран нлн вволнть нх с клавиатуры, причем реачнзацня этнх действий требует детального знанию тех нлн иных устройств ЭВМ. Так вот, чтобы избавить авторов программ ст знания этих деталей, избавить нх от необходимости выпнсывать этн действня в каждой программе заново, такие часто повторяющиеся действня описывают одын раз в анде соответствующих процедур н включают нх в состав ОС, н теперь все программы могут пользоваться нын.
Но кюс обращаться к зтнм процедурам? Конечно, можно использовать обычную коыанду вызова процедур (СА1.1.), но для этого надо знать начальные адреса зтнх процедур. А этн адреса, к сожалению, меняются от одной версии ОС к другой, причем версии ОС менаются достаточно часто, поэтому сегодня этн адреса однц, а завтра - другие. Учнтымм это, процедуры ОС прннято вызывазь несколько иначе - с помощью прерываннй, исходя нз следующего соображении: раз днялог-ынэи" яея программирование не немке ессемсяере!ВМ РС ОС "вступает в игру" при любом прерывании, то почему бы ие воспользоваться прерываниями и для вызова ее процедур. Конкретно эта идея реализуется так. Определенные номера прерываний оставляют иезаиятыми для прерываний от устройств ЭВМ и предназначают для вызова процедур ОС, для чего в соответствующие элементы вектора прерываний записываются начальные адреса этих процедур.
Поэтому, если выработать прерывание с одним из этих номеров, то будет вызвана соответствующая процедура. При этом ие надо знать точный адрес этой процедуры, а достаточно знать толыго номер прерываиия, по которой оиа вызывается. Номера же эти остаются одними и теми же во всех версиях ОС. Но для вызова таким образом процедур ОС надо уметь генерировать прерываиия из сбычиых программ. Для этого в систему команд ПК включена специальиая комаида - команда прерывания (1пгеггарг): глт за Эта команда вызывает искуссшеииое, иасильствеииое прерывание с номером 18 (Осм18<м255), а это значит, что начнет работать та процедура ОС, начальный адрес которой записан в элемеите вектора прерываний с номером 18. Закончив свою работу, эта процедура вериет управлеиие иа комацду программы, следующую за командой ПчТ.