Как читать и записывать регистры флагов x86 напрямую?

StackOverflow https://stackoverflow.com/questions/1406783

  •  05-07-2019
  •  | 
  •  

Вопрос

Из того, что я прочитал, кажется, что существует 9 разных флагов.Можно ли прочитать / изменить их напрямую?Я знаю, что могу узнать, например, установлен ли нулевой флаг после выполнения инструкции cmp / jmp, но я спрашиваю, возможно ли сделать что-то вроде

mov eax, flags

или что-то в этом роде.

Кроме того, для записи можно ли установить их вручную?

Это было полезно?

Решение

Некоторые флаги можно установить или снять непосредственно с помощью специальных инструкций:

  • CLC, STC, и CMC:очистите, установите и дополните флаг переноса
  • CLI и СТИ:снимите и установите флаг прерывания (что должно быть сделано атомарно).
  • CLD и ЗППП:очистите и установите флажок направления

Для считывания и записи флагов знака, нуля, вспомогательного переноса, четности и переноса вы можете использовать ЛАФ чтобы загрузить младшие 8 битов (эти 5 флагов плюс 3 неопределенных бита) в регистр AH, и вы можете использовать САХФ чтобы сохранить эти значения из AH обратно в регистр flags.

Вы также можете использовать PUSHF инструкция по помещению флагов в стек, чтению и изменению их в стеке, а затем использованию ПОПФ1 инструкция по их сохранению обратно в регистр флагов.

Обратите внимание, что вы не можете установить флаги VM и RF с помощью POPF - они сохраняют свои предыдущие значения.Аналогично, вы можете изменить уровень привилегий ввода-вывода только при выполнении с уровнем привилегий 0, а флаг прерывания может быть изменен только при выполнении с уровнем привилегий, по крайней мере, таким же привилегированным, как уровень привилегий ввода-вывода.


Сноска 1:

Обратите внимание , что popf работает довольно медленно на современных процессорах;видишь Агнер Фог руководство по оптимизации и таблицы инструкций.Он микрокодирован, потому что в режиме ядра он способен изменять IF, AC и уровень привилегий ввода-вывода.Мы несем ответственность независимо от режима работы текущих процессоров, потому что декодеры не чувствительны к режиму.

Если возможно, используйте lahf / sahf вместо pushf / popf для повышения производительности или сохраните один интересующий вас флаг, например setc al потом, позже add al, 255 чтобы установить CF = (AL!=0).Или setnc al / sub al, 1 или что там еще.Последовательности для установки или очистки SF или OF на основе регистра 0 или 1 также просты, с инвертированием флага или без него.

Другие советы

Вы можете использовать инструкции pushf и popf, которые поместят флаги в стек, вы можете изменить их, а затем вытащить обратно.

Если вам нужен только младший байт регистра флагов (который содержит SF, ZF, AF, PF, CF), то есть странная, но удобная инструкция LAHF (ха-ха), которая загружает нижние 8 битов флаги регистрируются в AH, а его аналог SAHF сохраняет AH во флаги.

В частности, для флага переноса x86 предлагает CLC, STC и CMC для очистки, установки и дополнения флага переноса соответственно.

Самый простой способ - использовать pushf / popf .

Если вы хотите переместить eflags в eax , используйте код ниже.

pushf                  # push eflags into stack
pop %eax               # pop it into %eax

SETcc ( Установить )

Это семейство инструкций - еще один способ наблюдать за некоторыми флагами / комбинациями флагов.

Он устанавливает значение байта на основе отдельных ФЛАГОВ.

Например, для CF:

stc
setc al
; al == 1

clc
setc al
; al == 0

Запускаемый восходящий поток GitHub с утверждениями.

Jcc

Это семейство инструкций, конечно, является еще одной возможностью для определенных флагов и может быть использовано для реализации SETcc:

jc set
mov al, 0
jmp end
set:
mov al, 1
end:

Запускаемый восходящий поток GitHub с утверждениями.

  • ЛАФ:загружает флаги состояния в AH
  • Копирует младший байт регистра EFLAGS, включая флаги Sign, Zero и Carry.
  • Сохраните копию флагов в переменной для сохранности

    .data
     saveflags BYTE ? 
    .code 
     lahf ; load flags into AH 
     mov saveflags,ah ; save them into a variable 
    
  • САХФ:сохраняет AH во флагах состояния

  • Копирует AH в младший байт регистра EFLAGS
  • Извлеките значение флагов, сохраненных ранее

    .code
     mov ah, saveflags ; load save flags into AH 
     sahf ; copy into flags register 
    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top