Регистр FLAGS — это регистр состояния , содержащий текущее состояние процессора x86 . Размер и значения битов флага зависят от архитектуры. Обычно он отражает результат арифметических операций, а также информацию об ограничениях, наложенных на работу процессора в текущий момент. Некоторые из этих ограничений могут включать предотвращение срабатывания некоторых прерываний, запрет на выполнение класса «привилегированных» инструкций. Дополнительные флаги состояния могут обходить отображение памяти и определять, какое действие процессор должен предпринять при арифметическом переполнении.
Флаги переноса, четности, вспомогательного переноса (или полупереноса ), нуля и знака включены во многие архитектуры (многие современные (RISC) архитектуры не имеют флагов, таких как перенос, и даже если они используют флаги, то полуперенос встречается редко, поскольку математика BCD больше не распространена, и даже имеет ограниченную поддержку в длинном режиме на x86-64 ).
В архитектуре i286 регистр имеет ширину 16 бит . Его последователи, регистры EFLAGS и RFLAGS (в современной x86-64 ), имеют ширину 32 и 64 бита соответственно. Более широкие регистры сохраняют совместимость со своими меньшими предшественниками.
Регистр флагов Intel x86 [1] | ||||||
---|---|---|---|---|---|---|
Кусочек # | Маска | Аббревиатура | Описание | Категория | =1 | =0 |
ФЛАГИ | ||||||
0 | 0x0001 | CF | Нести флаг | Статус | CY (переноска) | NC (без переноски) |
1 | 0x0002 | — | Зарезервировано, всегда 1 в EFLAGS [2] [3] | — | ||
2 | 0x0004 | ПФ | Флаг паритета | Статус | PE (четность) | PO (Четность нечетная) |
3 | 0x0008 | — | Зарезервировано [3] | — | ||
4 | 0x0010 | АФ | Вспомогательный флаг для переноски [4] | Статус | AC (вспомогательное снаряжение) | NA (без вспомогательного переноса) |
5 | 0x0020 | — | Зарезервировано [3] | — | ||
6 | 0x0040 | ЗФ | Нулевой флаг | Статус | ZR (Ноль) | NZ (не ноль) |
7 | 0x0080 | СФ | Флаг знака | Статус | НГ (отрицательно) | ПЛ (положительный) |
8 | 0x0100 | ТФ | Флаг-ловушка (один шаг) | Контроль | ||
9 | 0x0200 | ЕСЛИ | Флаг разрешения прерывания | Контроль | EI (Включить прерывание) | DI (Отключить прерывание) |
10 | 0x0400 | ДФ | Флаг направления | Контроль | DN (вниз) | ВВЕРХ (вверх) |
11 | 0x0800 | ИЗ | Флаг переполнения | Статус | OV (Переполнение) | NV (не переполнение) |
12–13 | 0x3000 | ИОПЛ | Уровень привилегий ввода-вывода (только 286+), всегда все единицы на 8086 и 186 | Система | ||
14 | 0x4000 | НТ | Флаг вложенной задачи (только 286+), всегда 1 на 8086 и 186 | Система | ||
15 | 0x8000 | МД | Флаг режима ( только для серии NEC V ), [5] зарезервирован на всех процессорах Intel. Всегда 1 на 8086/186, 0 на 286 и более поздних. | Контроль | (только NEC) Основной режим ( совместим с 186 ) | (только NEC) Режим эмуляции ( совместим с 8080 ) |
ЭФЛАГИ | ||||||
16 | 0x0001 0000 | РФ | Флаг возобновления (только 386+) | Система | ||
17 | 0x0002 0000 | ВМ | Флаг режима виртуального 8086 (только 386+) | Система | ||
18 | 0x0004 0000 | АС | Проверка выравнивания (486+, кольцо 3), проверка доступа SMAP ( Broadwell +, кольцо 0-2) | Система | ||
19 | 0x0008 0000 | ВИФ | Флаг виртуального прерывания (Pentium+) | Система | ||
20 | 0x0010 0000 | ВИП | Ожидается виртуальное прерывание (Pentium+) | Система | ||
21 | 0x0020 0000 | ИДЕНТИФИКАТОР | Возможность использования инструкции CPUID (Pentium+) | Система | ||
22–29 | 0x3FC0 0000 | — | Сдержанный | — | ||
30 | 0x4000 0000 | (никто) | Флаг загруженного расписания ключа AES [6] (только для процессоров с VIA PadLock ) | Система | ||
31 | 0x8000 0000 | ИИ | Альтернативный набор инструкций включен ( только для процессоров VIA C5XL ) [7] | Система | ||
РФЛАГС | ||||||
32‑63 | 0xFFFF FFFF… …0000 0000 | — | Сдержанный | — |
Примечание: Столбец маски в таблице представляет собой битовую маску AND (в шестнадцатеричном формате) для запроса флага(ов) в значении регистра FLAGS.
Все регистры FLAGS содержат коды условий , биты флагов, которые позволяют результатам одной инструкции машинного языка влиять на другую инструкцию. Арифметические и логические инструкции устанавливают некоторые или все флаги, а инструкции условных переходов выполняют переменные действия на основе значения определенных флагов. Например, jz
(Jump if Zero), jc
(Jump if Carry) и jo
(Jump if Overflow) зависят от определенных флагов. Другие условные переходы проверяют комбинации нескольких флагов.
Регистры FLAGS можно перемещать из стека или в стек. Это часть работы по сохранению и восстановлению контекста ЦП, против такой процедуры, как процедура обслуживания прерываний, чьи изменения в регистрах не должны быть видны вызывающему коду. Вот соответствующие инструкции:
В 64-битном режиме доступны PUSHF/POPF и PUSHFQ/POPFQ, но не PUSHFD/POPFD. [8] : 4–349, 4–432
Нижние 8 бит регистра FLAGS также открыты для прямой загрузки/сохранения с помощью SAHF и LAHF (загрузка/сохранение AH во флаги).
Возможность вставлять и выталкивать регистры FLAGS позволяет программе манипулировать информацией во FLAGS способами, для которых не существует инструкций машинного языка. Например, инструкции cld
и std
очищают и устанавливают флаг направления (DF) соответственно; но нет инструкции для дополнения DF. Этого можно добиться с помощью следующего ассемблерного кода :
; Это код 8086 с 16-битными регистрами, помещенными в стек, ; а регистр флагов в этом процессоре занимает всего 16 бит. pushf ; Используем стек для передачи FLAGS pop ax ; … в регистр AX push ax ; и копируем их обратно в стек для хранения xor ax , 400h ; Переключаем (инвертируем, «дополняем») только DF; остальные биты не изменяются push ax ; Снова используем стек для перемещения измененного значения popf ; … в регистр FLAGS ; Вставляем сюда код, требующий дополнения флага DF popf ; Восстанавливаем исходное значение FLAGS
Манипулируя регистром FLAGS, программа может определить модель установленного процессора. Например, флаг выравнивания можно изменить только на 486 и выше. Если программа попытается изменить этот флаг и обнаружит, что изменение не сохранилось, процессор более ранний, чем 486.
Начиная с Intel Pentium , инструкция CPUID сообщает модель процессора. Однако указанный выше метод остается полезным для различения более ранних моделей.