Защищенный режим процессоров Intel

         

Команды CALL и JMP


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

Во-первых, программист может указать в качестве операнда селектор дескриптора вызываемого сегмента кода.

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

Первый способ называется прямым вызовом, второй - вызовом через вентиль вызова.

Рассмотрим сначала прямой вызов сегмента.

В этом случае операнд команды вызова - селектор дескриптора вызываемого или, другими словами, целевого сегмента.

На выполнение прямого вызова целевого сегмента или прямого перехода к целевому сегменту влияет бит подчинения C, который располагается в бите 2 байта доступа дескриптора целевого сегмента.

Если бит C установлен в 0, целевой сегмент называется несогласованным. Несогласованный сегмент может быть вызван только такой программой, которая имеет большие или такие же привилегии, что и целевой сегмент. Т.е. должно выполняться условие CPL<= DPL.

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

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


Если программный сегмент, располагающийся в ядре операционной системы, должен вызываться как самой операционной системой в нулевом кольце так и программами пользователя в менее привилегированных кольцах, можно применить согласованный сегмент.

В согласованном сегменте кода бит подчинения C байта доступа установлен в 1. Согласованный сегмент можно вызывать из программ, находящихся в любом кольце. Но в любом случае при вызове этот сегмент будет выполняться с привилегиями вызывающей программы. Если согласованный сегмент вызывается из кольца 0, он будет выполняться с уровнем привилегий 0, если из кольца 3 - с уровнем привилегий 3.

Другой способ выполнить межсегментную передачу управления - использовать передачу управления через вентиль вызова.

В этом случае команды CALL или JMP адресуются к дескриптору с типом вентиля вызова. Формат этого дескриптора показан на рис. 11.



Рис. 11. Дескриптор вентиля вызова.

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

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

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

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

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


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