Механизм шлюзов для передачи управления на сегменты кода с другими уровнями привилегий



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


Рис. 3.9. Механизм шлюзов для перехода на другой уровень привилегий

Помимо дескрипторов сегментов системными объектами, с которыми работает микропроцессор, являются специальные системные дескрипторы, названные шлюзами или вентилями. Главное различие между дескриптором сегмента и шлюзом вызова заключается в том, что содержимое дескриптора указывает на сегмент в памяти, а шлюз обращается к дескриптору. Другими словами, если дескриптор служит механизмом отображения памяти, то шлюз служит механизмом перенаправления.
Для получения доступа к более привилегированному коду задача должна обратиться к нему не непосредственно (путем указания дескриптора этого кода), а обращением к шлюзу этого сегмента (рис. 3.10).
В этом дескрипторе вместо адреса сегмента указываются селектор, позволяющий найти дескриптор искомого сегмента кода, и адрес (смещение назначения), с которого будет выполняться подчиненный сегмент, то есть полный 32-битный адрес. Формат дескриптора шлюза приведен на рис. 3.11. Адресовать шлюз вызова можно с помощью команды CALL. По существу, дескрипторы шлюзов вызова не являются дескрипторами (сегментов), но они могут быть расположены среди обычных дескрипторов в дескрипторных таблицах процесса. Смещение, указываемое в команде перехода на другой сегмент (FAR CALL), игнорируется, и фактически осуществляется переход на команду, адрес которой определяется через смещение из шлюза вызова. Этим гарантируется попадание только на разрешенные точки входа в подчиненные сегменты.


Рис. 3.10. Переход на сегмент более привилегированного кода


Рис. 3.11. Формат дескриптора шлюза

Введены следующие правила использования шлюзов:

  • значение DPL шлюза вызова должно быть больше или равно значению текущего уровня привилегий CPL;
  • значение DPL шлюза вызова должно быть больше или равно значению поля RPL селектора шлюза;
  • значение DPL шлюза вызова должно быть больше или равно значению DPL целевого сегмента кода;
  • значение DPL целевого сегмента кода должно быть меньше или равно значению текущего уровня привилегий CPL.

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

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

Изложенный коротко аппаратный механизм защиты по привилегиям оказывается довольно сложным и жестким. Однако поскольку все практические ситуации учесть в схемах микропроцессора невозможно, то при разработке процедур операционных систем и иного высоко привилегированного кода следует придерживаться приведенных ниже рекомендаций, заимствованных из книги [22].
Основной риск связан с передачей управления через шлюз вызова более привилегированной процедуре. Нельзя предоставлять вызывающей программе никаких преимуществ, вытекающих из-за временного повышения привилегий. Это замечание особенно важно для процедур нулевого уровня привилегий (PL0-процедур).
Вызывающая программа может нарушить работу процедуры, передавая ей "плохие" параметры. Поэтому целесообразно как можно раньше проконтролировать передаваемые процедуре параметры. Шлюз вызова сам по себе не проверяет значений параметров, которые копируются в новый стек, поэтому достоверность каждого передаваемого параметра должна контролировать вызванная процедура. Вот некоторые способы контроля передаваемых параметров.

1. Следует проверять счетчики циклов и повторений на минимальные и максимальные значения.

2. Необходимо проверить 8- и 16-битные параметры, передаваемые в 32-битных регистрах. Когда процедуре передается короткий параметр, его следует расширить со знаком или нулем для заполнения всего 32-битного регистра.

3. Следует стремиться свести к минимуму время работы процессора с запрещенными прерываниями. Если процедуре требуется запрещать прерывания, необходимо, чтобы вызывающая программа не могла влиять на время нахождения процессора с запрещенными прерываниями (флажок IF=0).

4. Процедура никогда не должна воспринимать как параметр код или указатель кода.

5. В операциях процессора следует явно задавать состояние флажка направления DF для цепочечных команд.

6. Заключительная команда RET или RETn в процедуре должна точно соответствовать полю счетчика WC шлюза вызова; при этом n = 4x, так как счетчик задает число двойных слов, а n соответствует байтам.

7. Не следует применять шлюзы вызовов для функций, которым передается переменное число параметров (см. рекомендацию 6). При необходимости нужно воспользоваться счетчиком и указателем параметров.

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

9. В процедуре следует сохранять и восстанавливать все сегментные регистры. Иначе, если какой-либо сегментный регистр привлекался для адресации данных, недоступных вызывающей программе, процессор автоматически загрузит в него пустой селектор.

Рекомендуется контролировать все обращения к памяти. Нетрудно представить себе, что РL3-программа передаст PL0-процедуре указатель селектор:смещение и запросит считывание или запись нескольких байтов по этому адресу. Типичным примером может служить процедура дискового ввода/вывода, которая воспринимает как параметр системный номер файла, счетчик байт и адрес, по которому записываются данные с диска. Хотя PL0-процедура имеет привилегии для производства такой операции, но у РL3-программы разрешения на это может не быть.

Типы адресов

Для идентификации переменных и команд используются символьные имена (метки), виртуальные адреса и физические адреса (рисунок 2.7).

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

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

Рис. 2.7. Типы адресов

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

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

В некоторых случаях (обычно в специализированных системах), когда заранее точно известно, в какой области оперативной памяти будет выполняться программа, транслятор выдает исполняемый код сразу в физических адресах.

18. Адресация порта ввода-вывода

Этот тип адресации обеспечивает доступ к устрой­ствам ввода-вывода (В/В), присоединенным к В/В области памяти 8088. Область В/В 8088 в допол­нение к мегабайтовой памяти содержит еще 65 Кбайт (рис. 2.31). Эта область В/В не является сегментируе­мой и может выполняться как отдельно, так и вместе со всей памятью 8088. В последнем случае уменьшает­ся мегабайтовая память на 64 К, но обеспечивается дополнительная гибкость при программировании, так как все рассмотренные ранее типы адресации могут обеспечить доступ к этой области.

Каждый байт области В/В 8088 может быть назна­чен в качестве адреса однозначно определяемого пор­та В/В. Таким образом, область В/В может обслу­жить 64 К (65536) 8-битовых портов В/В. Данные могут передаваться между накопителем и любым портом В/В, адресуемом внутри 64-килобайтовой области В/В. Регистр AL используется для передачи байта, а регистр АХ - для передачи слова. Для адре­сации порта В/В существуют команды IN (ввести из порта) и OUT (вывести в порт). Если номер порта находится в пределах 0 - 255 (десятичных чисел), он может быть определен частью машинной команды; если же номер порта превышает 255, то для его хра­нения используют регистр DX. прямая адресация. косвенная адресация косвенная адресация со смещением. индексная адресация. индексная адресация со смещением. адресация строк данных.

Прямая адресация

Простейшим типом адресации является прямая; она не использует никаких регистров. Исполнитель­ный адрес ЕА берется непосредственно из 16-битового поля смещения машинной команды.

Этот прямой адрес однозначно определяет байт или слово памяти, расположенные внутри сегмента. Прямая ад­ресация обычно используется для работы с простыми переменными или константами. В процессоре 8088 должно соблюдаться условие, согласно которому пря­мой адрес не выходит за пределы сегмента данных. Поскольку в программах прямой адрес может опреде­ляться относительно любого из четырех доступных сегментов, для его модификации возможно примене­ние префиксных команд. При использовании прямой адресации в поле Mod содержится число 00, а в поле Rm - число 10.

Пусть, например, в программе, написанной на язы­ке ассемблера, регистр сегмента данных DS содержит 04В5Н, а байт 1400Н текущего сегмента данных - символическое имя LOCI. Машинная команда С606001402 (MOV LOC1.02) предписывает запомнить по перемещаемому адресу 1400Н сегмента данных шестнадцатеричное число 02. Поле смещения коман­ды содержит число 1400Н и интерпретируется как исполнительный адрес ЕА. Действительный физический 20-битовый адрес, определяемый устройством связи, в этом случае соответствует 05F50H (4В50Н+1400Н).

Для прямой адресации используют два специаль­ных вида адресации: относительную и абсолютную.

При относительной адресации поле смещения представляется 8-битовым числом со знаком. Испол­нительный адрес ЕА при этом определяется в резуль­тате сложения содержимого поля смещения и регист­ра указателя команд IP (рис. 2.25,В). Относительную адресацию используют для команд условных перехо­дов, таких, как JE (переход по равенству), JO (пере­ход по переполнению). При использовании относи­тельной адресации байт адресации (Mod/Reg/Rm) не требуется.

При абсолютной адресации часть команды пред­ставляет собой 32-битовый указатель, определяющий физический адрес в памяти МП 8088. Младшее слово указателя рассматривается при этом как переме­щаемый адрес сегмента, базовым адресом которого является старшее слово указателя. При абсолютной адресации байт адресации (Mod/Reg/Rm) также не требуется.

Косвенная адресация

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

При косвенной адресации существует одно исклю­чение: для команд JMP (переход) и CALL (вызов процедур) в качестве исполнительного адреса может выступать содержимое любого из 16-битовых регист­ров общего назначения (АХ, ВХ, СХ, DX, SI, DI, BP, SP).

Пусть, например, в программе на языке ассембле­ра регистр DS содержит число 14С5Н. Если содержи­мым регистра SI является число 28FFH, команда С60410 (MOV[SI], ЮН) запоминает шестнадцатерич­ное число 10 в байте 28FFH сегмента данных. В этом случае содержимое регистра SI служит исполнитель­ным адресом. Действительный физический 20-битовый адрес памяти, соответствующий перемещаемому адре­су 28FFH, при этом равен 1754FH (14C50H+28FFH).


Дата добавления: 2018-05-12; просмотров: 485; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!