10.7.3. Проверка привилегий

Все неравенства здесь арифметические, то есть А > В означает, что уровень, привилегий А меньше, чем В:

загрузке регистра DS, ES, FS или GS должно выполняться условие: DPL > max(RPL,CPL);

а при загрузке регистров SS должно выполняться условие: DPL = CPL = RPL;

□ при дальних JMP, CALL, RET на неподчиненный сегмент кода должно вы­полняться условие: DPL = CPL (RPL игнорируется);

□ при дальних JMP, CALL, RET на подчиненный сегмент кода должно выпол­няться условие: CPL > DPL. При этом CPL не изменяется;

□ при дальнем CALL на шлюз вызова должны выполняться условия: CPL < DPL шлюза, RPL < DPL шлюза, CPL > DPL сегмента;

□ при дальнем JMP на шлюз вызова должны выполняться условия: CPL< DPL шлюза, RPL < DPL шлюза, CPL > DPL сегмента, если он подчиненный, CPL = DPL сегмента, если он неподчиненный.

При вызове процедуры через шлюз на неподчиненный сегмент кода с другим уровнем привилегий процессор выполняет переключение стека. В сегменте TSS текущей задачи всегда хранятся значения SS:ESP для стеков уровней привиле­гий О, 1 и 2 (но не стек для уровня привилегий 3, потому что нельзя выполнять передачу управления на уровень 3, кроме как при помощи команд RET/IRET). При переключении стека в новый стек помещаются, до обратного адреса, пара­метры (их число указано в дескрипторе шлюза вызова), флаги или код ошибки (в случае INT), старые значения SS:ESP, которые команда RET/IRET использует для обратного переключения. То, что надо выполнить возврат из процедуры, RET определяет так: RPL селектора, оставленного в стеке, больше (менее привилеги­рованный), чем CPL.

Даже если операционная система не поддерживает многозадачность, она дол­жна оформить сегмент TSS с действительными SS:ESPnJui стеков всех уровней,

если она собирается использовать уровни привилегий.