Встроенные средства защиты. Принципы модульности и перемещаемости. Проверка привилегированности сегмента, страница 13


параметр 3     (Е)SP               параметр 3

 


старый CS 

 


старый IP        (Е)SP

 


Рис. Состояние стека при вызове процедуры с передаваемыми параметрами

Итак, при использовании шлюзов вызовов можно вызвать более привилегированную процедуру из менее привилегированной, при этом в процессе вызова для более защищенной вызываемой процедуры создается новый стек. Вершины стеков каждого привилегированного уровня хранятся в соответствующих полях сегмента состояния задачи TSS (ОС создает отдельный TSS для любой задачи). При межсегментных вызовах ОС инициализирует регистры SS и (Е)SP исходными значениями из TSS. В частности, если дескриптор вызываемого кодового сегмента имеет значение DPL = 0, то при его вызове через шлюз в регистры  SS и (Е)SP будут загружены значения SS0 и (Е)SP0.

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

Сегмент данных.  Сегмент данных нельзя выполнять. Любая попытка выполнить команду из  сегмента данных приводит к  особому случаю защиты.

В поле TYPE дескриптора сегмента данных (табл.) дополнительно кодируются бит разрешения записи W  (бит 1) и бит расширения вниз ED   (бит 2).

Бит разрешения записи W  (Write) разрешает (W = 1)  или запрещает (W = 0) запись в сегмент данных. Чтение данных из сегмента данных всегда разрешено. Если (W = 0), то любая попытка записи в  сегмент данных вызывает  особый случай защиты.

Бит направления расширения  ED (Expand Down) определяет размещение сегмента данных относительно базового адреса. При  ED = 0 (расширение вверх) данные в сегменте размещаются в направлении возрастания адресов от базового адреса до границы, определяемой суммой базового адреса и размера (предела) сегмента. При ED = 1 (расширение вниз) данные в сегменте располагаются в направлении уменьшения адресов. При обращении к памяти параллельно с преобразованием адреса процессор 80х86 всегда контролирует смещение и следит, чтобы смещение было меньше или равно пределу. Если смещение оказывается больше предела, то фиксируется особый случай защиты. Бит ED управляет интерпретацией поля предела дескриптора.

Бит расширения вниз ED = 1 используется для выделения (кодирования) сегментов стека, которые расширяются вниз в область младших адресов.

В сегментах стека данные размещаются, начиная  с ячейки, адрес которой равен базовому плюс размер сегмента (предельное значение адреса вершины стека для 32-разрядных процессоров  равно FFFFFFFFh).  Остальные ячейки стека имеют меньшие адреса вплоть до нижней границы стека, адрес которой равен базовому адресу сегмента, указанному в дескрипторе. Так как сегменты стека “растут вниз”,  то для них необходимо, чтобы смещение было строго больше предела. По этой причине стековые сегменты выделяют битом ED = 1. Для стековых сегментов, если смещение оказывается меньше или равно пределу, то фиксируется особый случай защиты.

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