Как читать и записывать регистры флагов x86 напрямую? - PullRequest
18 голосов
/ 10 сентября 2009

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

mov eax, flags

или что-то.

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

Ответы [ 6 ]

28 голосов
/ 14 сентября 2009

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

  • CLC , STC и CMC : сбросить, установить и дополнить флаг переноса
  • CLI и STI : очистить и установить флаг прерывания (что должно быть сделано атомарно)
  • CLD и STD : очистить и установить флаг направления

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

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

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


Сноска 1:

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

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

8 голосов
/ 10 сентября 2009

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

5 голосов
/ 14 сентября 2009

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

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

2 голосов
/ 23 января 2019

Простейшим способом является использование pushf / popf .

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

pushf                  # push eflags into stack
pop %eax               # pop it into %eax
1 голос

SETcc

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

Устанавливает значение байта на основе отдельных флагов.

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

stc
setc al
; al == 1

clc
setc al
; al == 0

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

Jcc

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

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

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

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

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

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

    .code
     mov ah, saveflags ; load save flags into AH 
     sahf ; copy into flags register 
    
...