Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
POP
Влияние команды на флаги и форматы команды:
|
|
|
|
|
|
|
|
|
BF /0 |
POP m16 |
Загрузить слово из вершины стека в m16 |
8086 |
pop word ptr [di] |
BF /0 |
POP m32 |
Загрузить двойное слово из вершины стека в m16 |
Intel386 |
pop dword ptr mem |
58+rw |
POP r16 |
Загрузить слово из вершины стека в r16 |
8086 |
pop cx |
58+rd |
POP r32 |
Загрузить двойное слово из вершины стека в r32 |
Intel386 |
pop edi |
1F |
POP DS |
Загрузить слово из вершины стека в DS |
8086 |
pop ds |
07 |
POP ES |
Загрузить слово из вершины стека в ES |
8086 |
pop es |
17 |
POP SS |
Загрузить слово из вершины стека в SS |
8086 |
pop es |
0F A1 |
POP FS |
Загрузить слово из вершины стека в FS |
Intel386 |
pop fs |
0F A9 |
POP GS |
Загрузить слово из вершины стека в GS |
Intel386 |
pop gs |
Описание:
Команда POP заменяет содержимое операнда памяти, регистра или сегментного регистра значением из вершины стека. Текущий атрибут размера операнда в дескрипторе стекового сегмента (бит B) определяет размерность указателя стека: SP используется, если этот атрибут равен 16 бит и ESP — если 32 бита. Текущий атрибут размера операнда кодового сегмента определяет размерность пересылаемых данных (16 или 32 бита). Текущий атрибут размера адреса определяет размерность адреса при обращении к операнду-назначению команды в памяти. После выборки данных указатель стека (E)SP увеличивается на 2 при 16-битном размере операнда для кодового сегмента или на 4 при 32-битном размере операнда для кодового сегмента, после чего он указывает на новую вершину стека.
Если операнд-назначение — сегментный регистр (DS, ES, FS, GS или SS), то извлекаемое значение должно быть корректным селектором. В защищенном режиме загрузка селектора инициирует автоматическую загрузку информации из соответствующего дескриптора в скрытую часть сегментного регистра, а также проверку правильности информации селектора и дескриптора.
Нулевой селектор (0000h, … 0003h) может быть загружен в регистры DS, ES, FS или GS не вызывая исключений защиты. Однакоко попытка использования нулевых селекторов при обращении к памяти вызывает особую ситуацию #GP(0), и никакого обращения к памяти не происходит.
Сегментный регистр CS не может быть загружен командой POP. Для загрузки регистра CS должны использоваться команды JMP, CALL или RET.
Команда POP SS имеет специальное свойство, она запрещает все прерывания включая NMI до тех пор, пока не выполнится следующая команда. Это позволяет последовательно выполнить команды POP SS и MOV (E)SP,(E)BP без опасности использования ошибочного стека во время прерывания. Тем не менее, использование команды LSS является предпочтительным методом загрузки регистров SS и (E)SP. Существуют и другие команды, которые задерживают прием прерываний при выполнении следующей за ними команды, но комбинация таких команд (например, STI и POP SS) не означает, что прерывания не будут восприниматься на протяжении двух команд. Такие последовательности могут вызвать серьезные сбои, т.к. станет возможным поступление прерывания сразу после команды загрузки стекового сегмента SS.
Команда POP-в-память, которая использует указатель стека (E)SP в качестве базового регистра, обращается к памяти после извлечения данных из стека. Используемое при вычислении эффективного адреса значение является значением (E)SP после выполнения команды выборки. Для случая, когда в режиме 16-битной адресации значение регистра ESP после выборки операнда из стека становится равным 0h, фактический адрес, используемый при доступе к операнду-назначению в памяти, зависит от модели процессора и в общем случае не документирован.
Загрузка сегментного регистра в защищенном режиме вызывает специальные проверки и действия описанные ниже.
IF (Загружается SS)
THEN
IF (Селектор нулевой) THEN #GP(0);
Индекс селектора должен попадать в пределы таблицы дескрипторов, иначе #GP(Селектор);
RPL селектора должен быть равен CPL, иначе #GP(Селектор);
AR байт дескриптора должен задавать разрешенный для записи сегмент, иначе #GP(Селектор);
DPL в AR байте должен быть равен CPL, иначе #GP(Селектор);
Сегмент должен присутствовать, иначе #SS(Селектор);
Загрузить регистр SS селектором;
Загрузить скрытую часть регистра SS дескриптором;
FI;
IF (Загружается не нулевой селектор в регистр DS, ES, FS или GS)
THEN
AR байт дескриптора должен задавать сегмент данных или разрешенный для чтения кодовый сегмент, иначе #GP(Cелектор);
IF (Cегмент данных или несогласованный кодовый сегмент)
THEN RPL и CPL должны быть меньше или равны DPL в AR байте;
ELSE #GP(Cелектор);
FI;
Сегмент должен присутствовать, иначе #NP(Cелектор);
Загрузить сегментный регистр селектором;
Загрузить скрытую часть сегментного регистра дескриптором;
FI;
IF (загружается нулевой селектор в регистр DS, ES, FS или GS)
THEN
Загрузить сегментный регистр селектором;
Очистить бит достоверности (valide bit) в скрытой части сегментного регистра;
FI;
Операция:
IF StackAddrSize = 16
THEN
IF OperandSize = 16
THEN
DEST = (SS:SP); (* Копировать слово *)
SP = SP + 2;
ELSE (* OperandSize = 32 *)
DEST = (SS:SP); (* Копировать двойное слово *)
SP = SP + 4;
FI;
ELSE (* StackAddrSize = 32 *)
IF OperandSize = 16
THEN
DEST = (SS:ESP); (* Копировать слово *)
ESP = ESP + 2;
ELSE (* OperandSize = 32 *)
DEST = (SS:ESP); (* Копировать двойное слово *)
ESP = ESP + 4;
FI;
FI;
Особые ситуации защищенного режима:
#GP(0), если операнд-назначение находится в сегменте, запрещенном для записи, если используется некорректный эффективный адрес операнда в памяти в сегментах CS, DS, ES, FS, GS или нулевой селектор, а также при попытке загрузки регистра SS нулевым селектором.
#GP(Селектор), если индекс загруженного селектора не попадает в пределы таблицы дескрипторов, если при загрузке регистра SS запрашиваемый уровень привилегий селектора RPL или уровень привилегий соответствующего дескриптора сегмента DPL не равны текущему уровню привилегий CPL, если регистр SS загружается селектором, который указывает на сегмент запрещенный для записи, если регистр DS, ES, FS или GS загружается селектором сегмента, который не является доступным для чтения кодовым сегментом или сегментом данных, если регистр DS, ES, FS или GS загружается селектором сегмента, который является сегментом данных или несогласованным кодовым сегментом, и уровень привилегий дескриптора этого сегмента DPL меньше по значению запрашиваемого уровня привилегий селектора RPL и текущего уровня привилегий CPL.
#SS(0), если используется некорректный эффективный адрес операнда в сегменте SS, а также если текущий указатель стека не попадает в пределы стекового сегмента.
#SS(Селектор), если регистр SS загружается селектором сегмента, который помечен как неприсутствующий.
#NP(Селектор), если регистр DS, ES, FS или GS загружается селектором сегмента, который помечен как неприсутствующий.
#PF(Код ошибки), страничная ошибка.
#AC(0) при невыровненной ссылке в память при текущем уровне привилегий равном 3.
Особые ситуации режима реальной адресации:
#GP, если любая часть операнда находится вне пространства эффективных адресов в сегментах CS, DS, ES, FS или GS.
Особые ситуации режима V86:
Такие же, как и в режиме реальной адресации.
#PF(Код ошибки), страничная ошибка.
#AC(0) при невыровненной ссылке в память.
Замечание:
В процессоре Pentium III существуют некоторые ситуации, когда отладчик будет получать неверную информацию в регистрах отладки от команд MOV SS и POP SS. Обратитесь к технической документации Intel за описанием всех возможных случаев проявления ошибки.
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru