«Ближние» формы команды RET выполняют передачу управления только в пределах текущего кодового сегмента, и следовательно, для них выполняется только контроль границ. Смещение для команды, следующей после команды вызова CALL, извлекается из стека и помещается в регистр EIP. Процессор контролирует, чтобы это смещение не превосходило границу текущего кодового сегмента. «Дальняя» форма команды RET извлекает адрес возврата, помещенный в стек предыдущей командой CALL. В нормальных условиях указатель возврата всегда достоверен, поскольку он был сгенерирован командой CALL или INT. Тем не менее, процессор выполняет проверку привилегированности вследствие возможности того, что текущая процедура изменила указатель или не смогла правильно обработать стек. RPL селектора кодового сегмента, извлеченный из стека командой возврата, должен иметь уровень привилегированности вызывающей процедуры. Возврат в другой сегмент может изменить уровни привилегированности, но только в сторону более низких уровней. Когда команда RET встречает сохраненное значение CS, RPL которого численно больше CPL (т.е. имеет более привилегированный уровень), происходит возврат через уровни привилегированности. Такого рода возврат выполняет следующие шаги: 1. Выполняются проверки, показанные в Таблице 6-2 и регистры CS, EIP, SS и ESP загружаются их предыдущими значениями, которые были сохранены в стеке. 2. Старое содержимое регистров SS и ESP (из вершины текущего стека) настраивается по размеру в байтах, заданному в команде RET. Результирующее значение ESP не проверяется на границу стекового сегмента. Если значение ESP выходит за эту границу, то этот факт не распознается процессором до следующей стековой операции. (Содержимое регистров SS и ESP для возвращаемой процедуры не сохраняются; обычно их значения те же, что и хранимые в TSS). 3. Проверяется содержимое сегментных регистров DS, ES, FS и GS. Если хоть один из этих регистров ссылается на сегмент, DPL которого меньше нового CPL (включая конформные кодовые сегменты), сегментный регистр загружается пустым селектором (Индекс=0, TI=0). Сама команда RET в таких случаях не сообщает об исключениях; однако любые последующие ссылки к памяти при помощи сегментного регистра, содержпщего пустой селектор, вызовут исключение общей защиты. Это не позволяет менее привилегированным кодам обращаться к более привилегированным сегментам посредством селекторов, оставленных в сегментных регистрах более привилегированной процедурой.
Возврат из процедуры
05 Мар, 2009
