Проверка достоверности указателей необходима для поддержания изолированности разных уровней привилегированности. Она состоит из следующих шагов:
Проверка того, что процедура, создавшая данный указатель, имеет права доступа к данному сегменту.
Проверка того, что тип сегмента совместим с запрошенным способом его использования. 3. Проверка того, что смещение указателя не превышает границу сегмента.
Хотя процессор i486 автоматически выполняет проверки 2 и 3 при выполнении команды, в выполнении первой проверки должно участвовать программное обеспечение. Для этого предназначена команда ARPL. Программное обеспечение может также выполнять проверки 2 и 3 не дожидаясь, пока будет сгенерировано исключение процессора. Для этого предназначены команды LAR, LSL, VERR и VERW.
В режиме пользователя может выполняться дополнительная проверка выравнивания. Когда одновременно установлены бит AM регистра CR0 и флаг AC, невыравненные ссылки к памяти ведут к генерации исключения. Это свойство полезно для программ, которые используют два младшие бита указателя для идентификации типа данных адресуемой указателем структуры. Например, подпрограмма в библиотеке математических функций может принимать указатели на числовые структуры данных. Если типу такой структуры присвоен код 10 (двоичный), записанный в двух младших битах указателей на этот тип, то математические подпрограммы могут выполнять коррекцию по коду типа, прибавляя смещение -10 (двоичное). При получении подпрограммой неверного указателя типа ссылка будет невыравненной, что приведет к генерации исключения. Проверка выравнивания ускоряет работу программ, написанных на языках искуственного интеллекта, таких как Lisp, Prolog, Smalltalk и C++. Она также может использоваться для ускорения проверки признака типа указателя.
LAR (Загрузить права доступа) используется для верификации того, что указатель ссылается на сегмент с совместимостью по уровню привилегированности и типу. Команда LAR имеет один операнд - селектор сегмента для дескриптора, права доступа которого должны быть проверены. Дескриптор сегмента должен быть доступным для чтения на уровне привилегированности, численно большем (т.е. менее привилегированном), чем CPL и RPL селектора. Если дескриптор доступен для чтения, то команда LAR принимает второе двойное слово дескриптора, маскирует его значением 00FxFF00H, записывает результат в заданный 32-разрядный регистр назначения и устанавливает флаг ZF. (x означает, что соответствующие четыре бита записанного значения неопределены). Будучи однажды загруженным, прова доступа могут быть затем проверены. Команда LAR позволяет тестировать все допустимыке типы дескрипторов. Если RPL или CPL превышает DPL, или если селектор сегмента превышает границу для таблицы дескрипторов, права доступа не возвращаются, и флаг ZF очищается. Доступ к конформным кодовым сегментам допускается из любых уровней привилегированности.
LSL (Загрузить границу сегмента) позволяет программно тестировать границу дескриптора сегмента, если дескриптор, на который ссылается селектор сегмента (в памяти или в регистре), доступен для чтения на текущем CPL. Команда LSL загружает заданнный 32-разрядный регистр 32-разрядным гранулированным побайтно значением границы, вычисленным на основе конкатенированных полей границы и бита грануляции G дескриптора. Это может быть сделано только для дескрипторов, описывающих сегменты (данных, кода, состояния задачи и таблиц дескрипторов); дескрипторы шлюзов таким способом недоступны. (В таблице 6-3 подробно перечислено, какие типы допустимы, а какие нет). Интерпретация границы зависит от типа сегмента. Например, сегменты данных, расширяющиеся вниз (стековые сегменты) рассматривают границу иначе, чем все прочие типы сегментов. Для обеих команд, LAR и LSL, флаг ZF устанавливается в том случае, если загрузка была выполнена успешно; в противном случае флаг ZF очищается.
Таблица 6-3. Допустимые типы дескрипторов команды LSL-----------------------------------------------------------------Код типа Тип дескриптора Допустим?----------------------------------------------------------------- 0 Зарезервирован Нет 1 Зарезервирован Нет 2 LDT Да 3 Зарезервирован Нет 4 Зарезервирован Нет 5 Шлюз задачи Нет 6 Зарезервирован Нет 7 Зарезервирован Нет 8 Зарезервирован Нет 9 Доступен TSS центрального процессора i486 Да A Зарезервирован Нет B Занят TSS центрального процессора i486 Да С Шлюз вызова центрального процессора i486 Нет D Зарезервирован Нет E Шлюз прерывания центрального процессора i486 Нет С Шлюз ловушки центрального процессора i486 Нет-----------------------------------------------------------------