32-разрядный регистр EFLAGS содержит некоторые флаги состояния и управления процессором, а также некоторые системные флаги (см. рисунок). После инициализации процессора, регистр флагов содержит значение 00000002h, его биты 1, 3, 5, 15 и 22..31 зарезервированы и программы не должны их использовать.
Некоторые флаги регистра EFLAGS можно изменять непосредственно, при помощи специальных команд (они описаны ниже). Для загрузки значений флагов в регистр EFLAGS и считываний из него предназначены команды LAHF, SAHF, PUSHF, PUSHFD, POPF и POPFD. Значение любого флага всегда можно проверить, для этого нужно сохранить содержимое регистра EFLAGS в стек, затем извлечь его в регистр общего назначения и проверить командами TEST и BT. Изменить значения флагов можно путём загрузки его через стек из регистра общего назначения, но некоторые флаги таким образом изменить нельзя (например, двухбитовое поле IOPL в защищённом режиме).
Регистр EFLAGS автоматически сохраняется процессором в стек при дальних вызовах и восстанавливается из него при дальних возвратах; при переключении задач процессор сохраняет содержимое EFLAGS в TSS старой задачи и загружает значение из TSS новой.
До появления 32-разрядного процессора Intel386, регистр флагов был 16-разрядным и назывался FLAGS. Начиная с процессора Intel386, регистр флагов - 32-разрядный и называется EFLAGS (Extended FLAGS - расширенный FLAGS); при этом регистр FLAGS является младшей половиной регистра EFLAGS, все флаги, которые используют процессоры 8086 и Intel286 находятся как раз в младшей половине EFLAGS (т.е. во FLAGS), поэтому можно рассматривать регистр флагов как единый и называть его EFLAGS.
Говоря о флагах используют два термина флаг установлен - это значит, что бит, который соответствует этому флагу, принял значение 1; флаг сброшен - значение 0. Флаги встречаются не только в регистре EFLAGS, в 32-разрядном процессоре есть много регистров, целиком или частично состоящих из флагов - регистры управления, отладки, тестирования, MSR и т.д., поэтому термины "сброс" и "установка" флага употребляются везде, где идёт речь об изменении флагов.
Формат регистра флагов EFLAGS
Флаги состояния
Флаги состояния отображают результаты целочисленных арифметических операций (ADD, SUB, MUL и пр.), этими флагами являются биты 0, 2, 4, 6, 7 и 11 регистра EFLAGS.
CF | (бит 0) Флаг переноса (Carry Flag = CF). Устанавливается, если арифметическая операция приводит к переносу или заёму в/из старшего разряда, таким образом, этот флаг показывает условие переполнения при выполнении арифметических операций. Также, этот флаг используется некоторыми командами сдвига - именно в него выдвигается "лишний" бит. Флаг CF наиболее удобно использовать при ветвлении программы, потому что, с одной стороны, множество команд взаимодействует с этим флагом, с другой стороны, простые команды условного перехода JC и JNC обеспечивают быстрый и компактный способ условной передачи управления.
|
PF | (бит 2) Флаг чётности (Parity Flag = PF). Устанавливается, если младший байт результата команды содержит чётное число бит, иначе - сбрасывается.
|
AF | (бит 4) Флаг коррекции (Adjust Flag = AF). Устанавливается, если арифметическая операция производит перенос или заём в/из 3-й бит результата, иначе - сбрасывается. Этот флаг используется для двоично-кодированной десятичной (BCD - Binary-Coded Decimal) арифметики.
|
ZF | (бит 6) Флаг нуля (Zero Flag = ZF). Устанавливается, если результат операции - нуль, иначе - сбрасывается.
|
SF | (бит 7) Флаг знака (Sign Flag = SF). Всегда равен значению старшего бита результата, который интерпретируется как знаковый в некоторых арифметических операциях (0/1 - число положительное / отрицательное).
|
OF | (бит 11) Флаг переполнения (Overflow Flag = OF). Устанавливается, если результат операции не помещается в операнд (слишком большое положительное или слишком маленькое для отрицательных знаковых чисел); иначе - сбрасывается. Этот флаг используется командами знаковой целочисленной арифметики.
|
Из этих флагов только CF можно менять непосредственно (командами STC, CLC и CMC). Также, этот флаг используют команды BT, BTS, BTR, BTC, сохраняя в него результат.
Флаги состояния используются командами целочисленной арифметики трёх типов - знаковой, беззнаковой и BCD. При переполнении, индикатором является:
для знаковой арифметики - флаг OF,
| для беззнаковой арифметики - флаг CF,
| для BCD-арифметики - флаг AF.
| | | |
Команды условного ветвления Jcc, SETcc, LOOPcc и CMOVcc используют один или несколько флагов состояния, проверяя различные условия.
DF | (бит 10) Флаг направления (Direction Flag = DF). Этот флаг управляет строковыми командами (MOVS, CMPS, SCAS, LODS и STOS). Если флаг DF установлен, то строковые команды обрабатывают строки данных, переходя от младших адресов к старшим (т.е. в обычном направлении); если флаг DF сброшен - то в обратном направлении. Для явного изменения этого флага предназначены команды STD и CLD.
|
Системные флаги и поле IOPL
Эти флаги предназначены для использования на системном уровне и подразумевается, что прикладные программы не должны менять их значения (а в защищённом режиме - не могут).
IF | (бит 9) Флаг разрешения прерываний (Interrupt enable Flag = IF). Управляет реакцией процессора на маскируемые аппаратные прерывания - если установлен, то в ответ на IRQ процессор генерирует прерывания, если сброшен - процессор не отвечает на них (но не игнорирует).
|
TF | (бит 8) Флаг ловушки (Trap Flag = TF). Если установлен, то процессор использует покомандную отладку текущей программы; если сброшен - программа выполняется обычным образом.
|
IOPL | (биты 12 и 13) Поле привилегий для ввода/вывода (I/O Privilege Level field = IOPL). Содержит для текущей задачи уровень привилегий для операций ввода/вывода. Текущий уровень привилегий (CPL - current privilege level) текущей задачи или программы должен быть численно меньше или равен значению в поле IOPL, для того, чтобы были возможны операции ввода/вывода. Это поле может меняться только командами POPF/POPFD и IRET и только на нулевом уровне привилегий.
|
NT | (бит 14) Флаг вложенной задачи (Nested Task flag = NT). Устанавливается процессором, когда происходит переход из одной задачи в другую командой CALL или аппаратным прерыванием и показывает, что текущая задача либо является вызванной из предыдущей (флаг NT=1), либо нет (NT=0).
|
RF | (бит 16) Флаг возобновления (Resume Flag = RF). Управляет ответом процессора на исключение отладки.
|
VM | (бит 17) Флаг режима виртуального 8086 (Virtual-8086 Mode flag = VM). Когда устанавливается, процессор переходит в режим виртуального 8086, когда сбрасывается - возвращается в защищённый режим.
|
AC | (бит 18) Флаг проверки выравнивания (Alignment Check flag = AC). Установка этого флага вместе с установленным флагом AM в CR0 заставляют процессор проверять выравнивание при доступе к памяти и в случае невыравненного доступа генерировать исключение.
|
VIF | (бит 19) Флаг виртуальных прерываний (Virtual Interrupt Flag = VIF). Это виртуальный образ флага IF, используется совместно с флагом VIP при включённом расширении режима виртуального 8086.
|
VIP | (бит 20) Флаг ожидания виртуального прерывания (Virtual Interrupt Pending flag = VIP). Устанавливается, когда возникает прерывание. Процессором только считывается и используется совместно с флагом VIF; изменяется только программно.
|
ID | (бит 21) Флаг идентификации (IDentification flag = ID). Если программа смогла установить и сбросить этот флаг, то это значит, что процессор может выполнить команду CPUID.
|
См. также:
Коды условий и флаги EFLAGS
Взаимодействие команд с флагами EFLAGS