Регистр ФЛАГОВ
Регистр 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 (Parity Odd) |
3 | 0x0008 | — | Сдержанный [3] | — | ||
4 | 0x0010 | ИЗ | Вспомогательный флаг переноса [4] | Статус | AC (дополнительная переноска) | NA (без вспомогательного переноса) |
5 | 0x0020 | — | Сдержанный [3] | — | ||
6 | 0x0040 | ЗФ | Нулевой флаг | Статус | ЗР (ноль) | Новая Зеландия (не ноль) |
7 | 0x0080 | Сан-Франциско | Знак флага | Статус | OF (отрицательный) | ПЛ (Положительный) |
8 | 0x0100 | ТФ | Флаг ловушки (один шаг) | Контроль | ||
9 | 0x0200 | ЕСЛИ | Флаг разрешения прерывания | Контроль | EI (Включить прерывание) | DI (отключить прерывание) |
10 | 0x0400 | ДФ | Флаг направления | Контроль | DN (Вниз) | ВВЕРХ (Вверх) |
11 | 0x0800 | ИЗ | Флаг переполнения | Статус | ОВ (переполнение) | NV (без переполнения) |
12–13 | 0x3000 | ИОПЛ | Уровень привилегий ввода-вывода (только 286+), всегда все 1 на 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 | VIP | Ожидание виртуального прерывания (Pentium+) | Система | ||
21 | 0x0020 0000 | ИДЕНТИФИКАТОР | Возможность использования инструкции CPUID (Pentium+) | Система | ||
22–29 | 0x3FC0 0000 | — | Сдержанный | — | ||
30 | 0x4000 0000 | (никто) | Флаг загрузки расписания ключей AES [6] (Только процессоры с VIA PadLock ) |
Система | ||
31 | 0x8000 0000 | ИИ | Альтернативный набор инструкций включен ( VIA C5XL ) только процессоры [7] |
Система | ||
RFLAGS | ||||||
32‑63 | 0xFFFF FFFF… …0000 0000 |
— | Сдержанный | — |
Примечание. Столбец маски в таблице представляет собой битовую маску AND (в виде шестнадцатеричного значения) для запроса флага(ов) в значении регистра FLAGS.
Использование
[ редактировать ]Все регистры FLAGS содержат коды условий , биты флагов, которые позволяют результатам одной инструкции машинного языка влиять на другую инструкцию. Арифметические и логические инструкции устанавливают некоторые или все флаги, а инструкции условного перехода выполняют переменное действие в зависимости от значения определенных флагов. Например, jz
(Перейти, если ноль), jc
(Прыжок при переносе) и jo
(Переход при переполнении) зависит от конкретных флагов. Другие условные переходы проверяют комбинации нескольких флажков.
Регистры FLAGS можно перемещать из стека или в стек. Это часть работы по сохранению и восстановлению контекста ЦП в отношении такой процедуры, как программа обслуживания прерываний, изменения в регистрах которой не должны быть видны вызывающему коду. Вот соответствующие инструкции:
- Инструкции PUSHF и POPF передают 16-битный регистр FLAGS.
- PUSHFD/POPFD (представленные в архитектуре i386 ) передают 32-битный двойной регистр EFLAGS.
- PUSHFQ/POPFQ (представленный в архитектуре x86-64 ) передает 64-битный регистр четырех слов RFLAGS.
В 64-битном режиме PUSHF/POPF и PUSHFQ/POPFQ доступны, а PUSHFD/POPFD — нет. [8] : 4–349, 4–432
Младшие 8 бит регистра FLAGS также открыты для прямых манипуляций с загрузкой/сохранением с помощью SAHF и LAHF (загрузка/сохранение AH во флаги).
Пример
[ редактировать ]Возможность загрузки и извлечения регистров FLAGS позволяет программе манипулировать информацией в FLAGS способами, для которых не существуют инструкции на машинном языке. Например, cld
и std
инструкции очищают и устанавливают флаг направления (DF) соответственно; но нет инструкции по дополнению DF. Этого можно добиться с помощью следующего ассемблерного кода :
; This is 8086 code, with 16-bit registers pushed onto the stack,
; and the flags register is only 16 bits with this CPU.
pushf ; Use the stack to transfer the FLAGS
pop ax ; … into the AX register
push ax ; and copy them back onto the stack for storage
xor ax, 400h ; Toggle (invert, ‘complement’) the DF only; other bits are unchanged
push ax ; Use the stack again to move the modified value
popf ; … into the FLAGS register
; Insert here the code that required the DF flag to be complemented
popf ; Restore the original value of the FLAGS
Манипулируя регистром FLAGS, программа может определить модель установленного процессора. Например, флаг выравнивания можно изменить только на 486 и выше. Если программа пытается изменить этот флаг и обнаруживает, что изменение не сохранилось, значит, процессор старше 486.
Начиная с Intel Pentium , инструкция CPUID сообщает модель процессора. Однако описанный выше метод остается полезным для различения более ранних моделей.
См. также
[ редактировать ]- Битовое поле
- Регистр управления
- Флаг процессора (x86)
- Слово состояния программы
- Регистр состояния
- язык ассемблера x86
- списки инструкций x86
Ссылки
[ редактировать ]- ^ Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32 (PDF) . Том. 1. Май 2012. С. 3–21.
- ^ Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32 (PDF) . Том. 1 декабря 2016 г. с. 78.
- ^ Jump up to: а б с «Реверс-инжиниринг кремния: недокументированные флаги 8085» . www.righto.com . Проверено 21 октября 2018 г.
- ^ Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32, том. 1 . Декабрь 2022 г. стр. 3–16.
- ^ NEC, Руководство пользователя 16-битной серии V , номер документа. U11301E, сентябрь 2000 г., с. 186
- ^ VIA, Руководство по программированию PadLock , версия 1.66, 4 августа 2005 г., стр. 7-8. Архивировано из оригинала 26 мая 2010 года.
- ^ VIA, Замечания по применению альтернативного набора команд процессора VIA C3 , версия 0.24, 2002 г. — подробные сведения о флаге EFLAGS.AI см. на рис. 2 на стр. 12 и в главе 4 на стр. 21.
- ^ Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32 (PDF) . Том. 2Б. Май 2012.