как изменить флаги вручную (в ассемблерном коде) для 8086?

#assembly #x86 #x86-16 #flags

#сборка #x86 #x86-16 #флаги

Вопрос:

Есть ли какой-нибудь способ изменить каждый флаг вручную? Или вам нужно использовать команду с результатом, который, как вы знаете, изменит их?

В основном я работаю с командой RCL , и я не хочу получать 1 в начале, поэтому я хочу изменить CF на 0, и я знаю, что я могу использовать такие команды, как:

 mov al, 0
shl al, 1
  

Но я хочу знать, есть ли какой-либо другой способ сделать это, без использования другого результата команд.

Я также хотел бы знать, можно ли также использовать способ, который вы можете мне показать, для изменения всех флагов, не только CF, но и OF, ZF и так далее.

Комментарии:

1. Может быть, sahf / popf?

2. В Carry есть специальные инструкции (в ответе), но, если вам повезет, иногда вы можете просто изменить порядок своего кода, например, если вам случится сделать some и / или /xor перед rcr , это тоже приведет к CF=0 . Часть сборки «игры в гольф» заключается в том, чтобы упорядочить вашу инструкцию таким образом, чтобы даже побочные продукты использовались повторно — когда это возможно. Но такой код сложнее читать и понимать, поэтому clc он идеально подходит для вас. Если вам нужно изменить флаг (RCL является действительной необходимостью), то очень вероятно, что у процессора есть какой-то способ, набор команд в целом хорошо работает вместе (хотя иногда это не очевидно).

3. На самом деле это довольно хороший способ решить эту проблему, но если я захочу установить флаги, это будет проблемой, но я обязательно использую команду clc, для меня это намного проще

Ответ №1:

Нет никакой инструкции, которая обрабатывала eflags бы как GP-регистр чтения-записи.
Цитирование Intel 1:

Некоторые из флагов в регистре EFLAGS можно изменять напрямую, используя специальные инструкции (описанные в следующих разделах). Нет инструкций, которые позволяют проверять или изменять весь регистр напрямую.
Для перемещения групп флагов в стек процедур или регистр EAX и обратно можно использовать следующие инструкции:
LAHF, SAHF, PUSHF, PUSHFD, POPF и POPFD. После того, как содержимое регистра EFLAGS было передано в стек процедур или регистр EAX, флаги могут быть проверены и изменены с помощью инструкций обработки битов процессора (BT, BTS, BTR и BTC).

eflags Регистр разделен на три группы: флаги состояния, флаги управления и системные флаги.

содержимое eflags

Из флагов состояния только CF можно управлять напрямую с помощью clc , stc , cmc .
Нет инструкции для чтения CF, но вы можете прочитать его косвенно с помощью инструкций, таких как cmovcc , adc , setcc . Все остальные флаги необходимо изменить с помощью специально разработанных арифметических инструкций или путем обработки содержимого группы состояний eflags into ah (with lahf ) илив стек (с pushfd ), а затем обратно в eflags sahf или popfd ).

В группе флагов управления есть только DF, которым можно управлять с cld помощью и std .
Для чтения текущего значения DF вам нужно использовать pushfd .

Системные флаги обычно обрабатываются косвенно, выполняя некоторые привилегированные операции, такие как переключение задачи, вход в режим v86 и тому подобное.
IF можно управлять напрямую с cli помощью and sti .
Всеми остальными флагами можно управлять только с pushfd помощью / popfd .


Для справки:

  • В 64-битном режиме регистр флага есть rflags , но старшие 32 бита пока зарезервированы, поэтому rflags обрабатываются как eflags .
  • pushfd нажимает eflags на стек. Существует также 16-разрядная версия pushf , которая использует только младшие 16 бит eflags . То же самое для popfd / popf .
  • lahf / sahf копирует только флаги состояния.

1 Руководства Intel, том 1, раздел 3.4.3.