Как читать и писать регистры x86 флаги напрямую?
Из того, что я читал, похоже, что существует 9 разных флагов. Можно ли их напрямую читать / изменять? Я знаю, что знаю, например, если флаг нуля установлен после выполнения инструкции cmp / jmp, но я спрашиваю, можно ли сделать что-то вроде
mov eax, flags
или что-то.
Кроме того, для записи, можно ли их вручную установить?
- Печать шестнадцатеричных цифр со сборкой
- Разница между JA и JG в сборке
- Возможно ли запустить двоичный файл x86 на процессоре ARM?
- Самый быстрый способ сделать горизонтальную векторную сумму float на x86
- Изменение режима округления с плавающей запятой
- Имеет ли смысл использовать инструкцию LFENCE для процессоров x86 / x86_64?
- В чем смысл «не временных» обращений к памяти в x86
- В чем смысл MOV (% r11,% r12,1),% edx?
- Почему нарушение «выходной зависимости» LZCNT имеет значение?
- Как выполнить инверсию _mm256_movemask_epi8 (VPMOVMSKB)?
- 16-разрядные режимы адресации NASM x86
- Векторизация с неуравновешенными буферами: использование VMASKMOVPS: создание маски из подсчета несоосности? Или не использовать этот insn вообще
- Какова цель инструкции LEA?
Некоторые флаги могут быть установлены или очищены непосредственно с помощью определенных инструкций:
- CLC , STC и CMC : очистить, установить и дополнить флаг переноса
- CLI и STI : очистить и установить флаг прерывания (который должен выполняться атомарно)
- CLD и STD : очистить и установить флаг направления
Для чтения и записи знака, нуля, вспомогательных переносов, четности и флагов переноса вы можете использовать LAHF для загрузки младших 8 бит (эти 5 флагов плюс 3 неопределенных бита) в регистр AH, и вы можете использовать SAHF для хранения этих значения от AH обратно в регистр флагов.
Вы также можете использовать инструкцию PUSHF, чтобы вставлять флаги в стек, читать и изменять их в стеке, а затем использовать инструкцию POPF для сохранения их обратно в регистр флагов.
Обратите внимание, что вы не можете установить флаги VM и RF с POPF – они сохраняют свои предыдущие значения. Аналогично, вы можете изменить уровень привилегий ввода-вывода при выполнении на уровне привилегий 0, а флаг прерывания может быть изменен только при выполнении на уровне привилегий, по крайней мере, как привилегированный, как уровень привилегий ввода-вывода.
Вы можете использовать команды pushf и popf, которые будут вставлять флаги в стек, вы можете их изменить, а затем отбросить.
Если вам нужен только младший байт регистра флагов (который содержит SF, ZF, AF, PF, CF), то есть нечетная, но удобная инструкция LAHF (ha ha), которая загружает нижние 8 бит регистра флагов в AH и его коллегой SAHF для хранения AH на флаги.
Для флага переноса специально x86 предлагает CLC, STC и CMC, чтобы очистить, установить и дополнить флаг переноса, соответственно.
SETcc
Это семейство команд является еще одним способом наблюдения за некоторыми флагами / комбинацией флагов. Например, для CF
:
stc setc al ; al == 1 clc setc al ; al == 0
Jcc
Это семейство команд, конечно, является другой возможностью для определенных флагов и может использоваться для реализации SETcc
:
jc set mov al, 0 jmp end set: mov al, 1 end:
- 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