Регистр FLAGS — это регистр состояния , который содержит текущее состояние процессора x86 . Размер и значение битов флага зависят от архитектуры. Обычно он отражает результат арифметических операций, а также информацию об ограничениях, наложенных на работу ЦП в текущий момент. Некоторые из этих ограничений могут включать предотвращение запуска некоторых прерываний, запрет выполнения класса «привилегированных» инструкций. Дополнительные флаги состояния могут обходить отображение памяти и определять, какое действие должен предпринять ЦП при арифметическом переполнении.
Флаги переноса, четности, вспомогательного переноса (или полупереноса ), нуля и знака включены во многие архитектуры (многие современные (RISC) архитектуры не имеют флагов, таких как перенос, и даже если они используют флаги, то полуперенос редко, поскольку математика BCD больше не распространена и даже имеет ограниченную поддержку в длинном режиме на x86-64 ).
В архитектуре i286 ширина регистра составляет 16 бит . Его преемники, регистры EFLAGS и RFLAGS (в современном x86-64 ), имеют ширину 32 и 64 бита соответственно. Более широкие регистры сохраняют совместимость со своими меньшими предшественниками.
Примечание. Столбец маски в таблице представляет собой битовую маску AND (в виде шестнадцатеричного значения) для запроса флага(ов) в значении регистра FLAGS.
Все регистры FLAGS содержат коды условий , биты флагов, которые позволяют результатам одной инструкции машинного языка влиять на другую инструкцию. Арифметические и логические инструкции устанавливают некоторые или все флаги, а инструкции условного перехода выполняют переменное действие в зависимости от значения определенных флагов. Например, jz
(Перейти при нуле), jc
(Перейти при переносе) и jo
(Перейти при переполнении) зависят от конкретных флагов. Другие условные переходы проверяют комбинации нескольких флажков.
Регистры 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 бит. толчок ; Используйте стек, чтобы перенести поп -топор ФЛАГОВ ; … в регистр AX вставьте ax ; и скопируйте их обратно в стек для хранения xor ax , 400h ; Переключить (инвертировать, «дополнить») только DF; остальные биты не изменяются push ax ; Используйте стек еще раз, чтобы переместить измененное значение popf ; … в регистр FLAGS ; Вставьте сюда код, который требовал, чтобы флаг DF был дополнен popf ; Восстановите исходное значение ФЛАГОВ.
Манипулируя регистром FLAGS, программа может определить модель установленного процессора. Например, флаг выравнивания можно изменить только на 486 и выше. Если программа пытается изменить этот флаг и обнаруживает, что изменение не сохранилось, значит, процессор старше 486.
Начиная с Intel Pentium , инструкция CPUID сообщает модель процессора. Однако описанный выше метод остается полезным для различения более ранних моделей.