Работа с Visual Studio.Net

         

Однозадачные операционные системы

Известно, что в каждый момент времени один процессор может выполнять лишь одну машинную команду. Процессор выполняет команды, последовательно выбирая их одну за другой из памяти в порядке возрастания адресов. Программист может нарушить этот порядок, вставив в программу команду условного или безусловного перехода, команду вызова функции или цикла (bne, call, jmp, loop). Операционная система, даже однозадачная, также может вмешаться в эту последовательность и отвлечься — временно оторваться от последовательности команд для выполнения каких-то других более важных, системных команд. Необходимость такой операции, называемой прерыванием, выясняется в процессе выборки очередной команды. Если система обнаруживает, что есть прерывание, то она запоминает в стеке контекст выполняемой программы: адрес текущей команды, ' содержимое регистров АУ, и переходит в режим обработки прерывания, то есть переключается на выполнение другой программы, вызвавшей прерывание. В системе

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

В оперативной памяти (RAM), даже в случае однозадачной ОС (операционная система), могут одновременно находиться несколько программ:

  • резидентная часть операционной системы; %
  • резидентные программы, которые запускает система или пользователь;
  • прикладная программа, выполняемая в данный момент.
В простейшем случае однозадачной ОС, такой как MS DOS, взаимодействие между тремя объектами, увязываемыми ОС, может протекать так, как показано на рис. 12.1.

Рис. 12.1. Диаграмма взаимодействия ОС с прикладной программой

Системный модуль, который подготавливает запуск прикладной программы, с тем чтобы вернуть управление обратно после ее завершения, называется program prefix segment. Он, так же как и модуль завершения программы пользователя, занимает определенное время и другие ресурсы системы. Если в процессе выполнения пользовательской прбграмме нужно выполнить какое-либо стандартное действие, например вывести строку символов на принтер, она может обратиться к стандартной подпрограмме, входящей в состав операционной системы. Такие стандартные действия, реализованные в ОС в виде отдельных процедур, принято называть системными сервисами. Обратите внимание на тот факт, что прикладная программа сама определяет момент предоставления ей системного сервиса. Программа при завершении, как вы знаете, может вернуть системе некий код (успех или неудача). Как программа может узнать о наступлении какого-либо события, внешнего по отношению к ней, например такого, как нажатие пользователем клавиши клавиатуры? Существуют два способа: по опросу готовности и с помощью механизма аппаратных прерываний. Клавиатура является устройством, о котором можно программно, анализируя содержимое программно-доступного регистра состояния клавиатуры, узнать, готово ли оно к обмену, то есть нажата ли клавиша. Алгоритм процедуры обмена, соответствующий первому способу, изображен на рис. 12.2. Он обладает тем недостатком, что при ожидании процессор используется неэффективно, то есть простаивает. Второй способ иллюстрируется рис. 12.3.

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

Рис. 12.2. Алгоритм опроса готовности

Рис. 12.3. Алгоритм обработки аппаратного прерывания

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

Рис. 12.4. Диаграмма асинхронного взаимодействия

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

Содержание раздела