Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
STI
Влияние команды на флаги и форматы команды:
|
|
1 |
|
|
|
|
|
|
FB |
STI |
Установить флаг разрешения внешних маскируемых прерываний |
8086 |
sti |
Описание:
Команда STI устанавливает флаг разрешения прерываний EFLAGS.IF. Установка флага EFLAGS.IF означает, что после команды, следующей за STI, микропроцессор начинает реагировать на запросы прерывания по входу INTR# (внешние маскируемые прерывания). Никакие другие флаги командой STI не изменяются.
В реальном режиме команда срабатывает без всяких условий и не может привести к генерации особых ситуаций.
В защищенном режиме флаг EFLAGS.IF устанавливается, только если текущий уровень привилегий как минимум такой же, как и уровень привилегий ввода/вывода (CPL ≤ EFLAGS.IOPL), в противном случае команда вызывает генерацию ошибки общей защиты (#GP). Такое поведение называется IOPL-чувствительностью и в защищенном режиме характерно также для команд CLI, IN, OUT, INS/NSB/INSW/INSD, OUTS/OUTSB/OUTSW/OUTSD
В режиме V86 успешное срабатывание команды STI (с учетом того что в задачах этого режима всегда CPL = 3) возможно только тогда, когда EFLAFS.IOPL = 3. В противном случае также генерируется ошибка общей защиты (#GP). В этом режиме IOPL-чувствительностью обладают также команды CLI, POPF/POPFD, PUSHF/PUSHFD, IRET/IRETD, INT n.
В процессорах, начиная с Pentium, поддерживаются специальные расширенные режимы обработки прерываний (виртуальные прерывания). Это позволяет обеспечить нормальное выполнение старого ПО, использующего команды управления внешними маскируемыми прерываниями (векторы от 32 до 255), в современной мультипроцессорной и мультизадачной программно-аппаратной среде. Указанные режимы управляются флагами CR4.PVI и CR4.VME и включают:
- режим с поддержкой виртуальных флагов прерываний (включается установкой флага CR4.PVI = 1 в защищенном режиме);
- режим EV86 (включается установкой флага CR4.VME = 1 в режиме V86).
В этих режимах флаг виртуального прерывания EFLAGS.VIF выступает виртуальным подобием флага EFLAGS.IF. При условии, что виртуальные прерывания инициализированы (CR4.PVI = 1 в защищенном режиме, CR4.VME = 1 в режиме V86), команда STI (как и команда CLI), выполняемая при текущем уровне привилегий равном 3 (CPL = 3), при соблюдении условия EFLAGS.IOPL < 3 (а в режиме V86 также должен быть сброшен флаг ожидания виртуального прерывания EFLAGS.VIP = 0) не вызывает генерацию ошибки общей защиты (#GP), а оказывает влияние на флаг EFLAGS.VIF, оставляя флаг EFLAGS.IF неизменным. Аналогичный специальный функционал для режима EV86 имеют также команды PUSHF, POPF, CLI, IRET и команда вызова программных прерываний INT n.
Таблица событий 6.116. указывает — какое действие из нижней части таблицы произойдет при условиях, стоящих в верхней части.
Таблица 6.116. Действия команды STI и условия их выполнения
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
|
x |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
x |
|
x |
x |
0 |
1 |
1 |
x |
x |
x |
x |
|
x |
x |
x |
x |
x |
0 |
x |
1 |
x |
|
x |
x |
x |
x |
x |
x |
1 |
0 |
x |
|
x |
≤ IOPL |
> IOPL |
3 |
< 3 |
x |
x |
x |
x |
|
x |
≥ CPL |
< CPL |
< 3 |
< CPL |
< 3 |
< 3 |
< 3 |
3 |
|
EFLAGS.IF = 1 |
+ |
+ |
+ |
||||||
EFLAGS.VIF = 1 |
+ |
+ |
|||||||
+ |
+ |
+ |
+ |
Операция:
IF CR0.PE = 0 (* Выполняется в режиме реальной адресации *)
THEN EFLAGS.IF = 1;
ELSE
IF EFLAGS.VM = 0 (* Выполняется в защищенном режиме *)
THEN
IF EFLAGS.IOPL = 3
THEN EFLAGS.IF = 1;
ELSE
IF CPL ≤ EFLAGS.IOPL
THEN EFLAGS.IF = 1;
ELSE (* CPL > EFLAGS.IOPL *)
IF (CPL = 3 and CR4.PVI = 1)
THEN EFLAGS.VIF = 1;
ELSE #GP(0);
FI;
FI;
FI;
ELSE (* Выполняется в виртуальном-8086 режиме *)
IF EFLAGS.IOPL = 3
THEN EFLAGS.IF = 1;
ELSE
IF (CR4.VME = 1 AND EFLAGS.VIP = 0)
THEN EFLAGS.VIF = 1;
ELSE #GP(0);
FI;
FI;
FI;
FI;
Особые ситуации защищенного режима:
#GP(0), если текущий уровень привилегий по значению больше (имеет меньше привилегий), чем уровень привилегий ввода/вывода – CPL > EFLAGS.IOPL (кроме режима с поддержкой виртуальных прерываний).
Intel386 … :
#UD при использовании префикса LOCK.
Pentium … (в режиме с поддержкой виртуальных прерываний – CR4.PVI = 1):
#GP(0), если текущий уровень привилегий меньше 3 и больше чем уровень привилегий ввода/вывода (EFLAGS.IOPL < CPL < 3).
Особые ситуации режима V86:
#GP(0), если не активирован режим EV86 (CR4.VME = 0), а также уровень привилегий ввода/вывода по значению меньше 3 (EFLAGS.IOPL < 3).
Intel386 … :
#UD при использовании префикса LOCK.
Pentium … (в режиме EV86):
#GP(0), если установлен флаг ожидания виртуального прерывания (EFLAGS.VIP = 1), а также уровень привилегий ввода/вывода по значению меньше 3 (EFLAGS.IOPL < 3).
Замечание:
После команды, следующей за STI, процессор начинает реагировать на запросы внешних маскируемых прерываний, только если эта команда не сбрасывает только что установленный флаг EFLAGS.IF. Например, если внешние прерывания были запрещены, и за командой STI сразу следует команда RET, то команда RET полностью исполнится перед тем, как внешние прерывания начнут распознаваться. Если внешние прерывания были запрещены и за командой STI следует команда CLI, которая снова сбрасывает флаг EFLAGS.IF, то внешние прерывания не распознаются.
В случае поступления запроса внешнего немаскируемого прерывания или генерации особой ситуации во время выполнения команды STI, прерывание будет иметь место перед выполнением следующей команды.
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru