Повторно-входимые (реентерабельные) модули.
Свойство исполняемого модуля быть реентерабельным (иногда говорят – параллельно используемым) является очень важным, особенно при написании системных программ. Модуль называется реентерабельным, если он допускает повторный вход в своё начало до выхода из этого модуля (для модулей на Ассемблере, как мы знаем, выход производится по команде возврата ret для процедур, по команде iret для обработчиков прерываний или по макрокоманде finish для основной программы).
Особо подчеркнём, что повторный вход в такой модуль производит не сам этот модуль, используя прямую или косвенную рекурсию, а другие программы, обычно при обработке сигналов прерываний. Таким образом, внутри реентерабельного модуля могут располагаться несколько текущих точек выполнения программы. Мы уже сталкивались с такой ситуацией при изучении системы прерываний, когда выполнение процедуры-обработчика прерывания с некоторым номером могло быть прервано новым сигналом прерывания с таким же номером, так что производился повторный вход в начало этой же процедуры до окончания обработки текущего прерывания.
Каждая текущая точка выполнения реентерабельной программы имеет, как мы уже упоминали, своё поле сохранение (иногда его называют контекстом процесса). При прерывании выполнения программы на этом поле сохраняются, в частности, все регистры, определяющие текущую точку выполнения (как сегментные регистры и регистр флагов, так и регистры общего назначения, и регистры для работы с вещественными числами).
Главное отличие реентерабельных программ от обычных рекурсивных процедур заключается именно в том, что при каждом входе в реентерабельную программу порождается новая текущая точка её выполнения и новое поле сохранения. Это позволяет продолжить выполнение реентерабельной программы с любой из этих нескольких текущих точек выполнения программы, восстановив значения всех регистров из поля сохранения этой точки программы.
Ниже перечислены основные свойства, которыми должен обладать модуль на Ассемблере, чтобы быть реентерабельным.
§ Модуль не меняет сегменты кода.
§ Модуль либо совсем не имеет собственных сегментов данных (т.е. использует сегмент данных другого модуля, на этот сегмент данных, как обычно, указывает значение регистра DS), либо при каждом входе получает новые копии своих сегментов данных.
§ При каждом входе в модуль он получает новый сегмент стека, пустой для основной программы и с копиями фактических параметров и адресом возврата для процедуры. Вообще говоря, этот сегмент стека является возможным местом и для расположения области сохранения модуля, хотя на современных ЭВМ область сохранения обычно размещается в так называемом пространстве ядра операционной системы, это место является защищённым от изменения со стороны программ обычных пользователей.
Реентерабельность является особенно важной при написании системных программ. Это следует из того, что если некоторая программа (например, компилятор с Ассемблера) является реентерабельной, то в оперативной памяти достаточно иметь только одну копию этой программы, которая может одновременно использоваться при компиляции любого числа программ на Ассемблере (отсюда второе название таких модулей – параллельно используемые).[61]
В современных ЭВМ большинство системных программ являются реентерабельными.
Дата добавления: 2015-10-05; просмотров: 1451;