Регистр флагов

Поделись знанием:
Перейти к: навигация, поиск

Регистр флагов — регистр процессора, отражающий текущее состояние процессора.





Архитектура x86

В микропроцессорах Intel 8086 имеет название FLAGS и является 16-разрядным. Расширенные регистры EFLAGS и RFLAGS, введённые в архитектурах IA-32 (процессоры 80386) и x86-64, являются 32-битными и 64-битными соответственно. Расширенные регистры сохраняют обратную совместимость.

Регистр флагов содержит группу флагов состояния, управляющий флаг и группу системных флагов[1]:

Регистр флагов Intel x86
Бит, № Обозначение Название Описание Тип флага Когда введён
FLAGS
0 CF Carry Flag Флаг переноса Состояние
1 1 Зарезервирован
2 PF Parity Flag Флаг чётности Состояние
3 0 Зарезервирован
4 AF Auxiliary Carry Flag Вспомогательный флаг переноса Состояние
5 0 Зарезервирован
6 ZF Zero Flag Флаг нуля Состояние
7 SF Sign Flag Флаг знака Состояние
8 TF Trap Flag Флаг трассировки (пошаговое выполнение) Системный
9 IF Interrupt Enable Flag Флаг разрешения прерываний Системный
10 DF Direction Flag Флаг направления Управляющий
11 OF Overflow Flag Флаг переполнения Состояние
12 IOPL I/O Privilege Level Уровень приоритета ввода-вывода Системный 80286
13
14 NT Nested Task Флаг вложенности задач Системный 80286
15 0 Зарезервирован
EFLAGS
16 RF Resume Flag Флаг возобновления Системный 80386
17 VM Virtual-8086 Mode Режим виртуального процессора 8086 Системный 80386
18 AC Alignment Check Проверка выравнивания Системный 80486SX
19 VIF Virtual Interrupt Flag Виртуальный флаг разрешения прерывания Системный Pentium
20 VIP Virtual Interrupt Pending Ожидающее виртуальное прерывание Системный Pentium
21 ID ID Flag Проверка на доступность инструкции CPUID Системный Поздние 80486[2]
22 0 Зарезервированы
31
RFLAGS
32 0 Зарезервированы
63

Значение некоторых флагов в регистре флагов можно изменять напрямую, с помощью специальных инструкций (например, CLD для сброса флага направления), но нет инструкций, которые позволяют обратиться (проверить или изменить) к регистру флагов как к обычному регистру. Однако, можно сохранять регистр флагов в стек или регистр (E)AX и восстанавливать регистр флагов из них с помощью инструкций LAHF, SAHF, PUSHF, PUSHFD, POPF и POPFD.

При приостановке задачи (используя многозадачные возможности процессора), процессор автоматически сохраняет значение флага регистров в TSS (task state segment), при активизации новой задачи процессор загружает регистр флагов из TSS новой задачи.

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

Флаги состояния в активном состоянии

Флаги состояния (биты 0, 2, 4, 6, 7 и 11) отражают результат выполнения арифметических инструкций, таких как ADD, SUB, MUL, DIV.

  • PF — устанавливается, если младший значащий байт результата содержит чётное число единичных (ненулевых) битов. Изначально этот флаг был ориентирован на использование в коммуникационных программах: при передаче данных по линиям связи для контроля мог также передаваться бит чётности (см., например: RS-232#Принцип работы) и инструкции для проверки флага чётности облегчали проверку целостности данных.
  • AF — устанавливается при переносе или заёме из бита 4 результата. Этот флаг ориентирован на использование в двоично-десятичной (binary coded decimal, BCD) арифметике.
  • ZF — устанавливается, если результат машинной операции по модулю 2 в степени k (где k - разрядность ячейки) равен нулю.
  • SF — равен значению старшего значащего бита результата, который является знаковым битом в знаковой арифметике.
  • OF — устанавливается, если целочисленный результат слишком длинный для размещения в целевом операнде (регистре или ячейке памяти). Этот флаг показывает наличие переполнения в знаковой целочисленной арифметике (в дополнительном коде).

Из перечисленных флагов только флаг CF можно изменять напрямую с помощью инструкций STC, CLC и CMC. Также, битовые инструкции (BT, BTS, BTR и BTC) копируют указанный бит во флаг CF.

Флаги состояния позволяют одной и той же арифметической инструкции выдавать результат трёх различных типов: беззнаковое, знаковое и двоично-десятично кодированное (BCD) целое число. Если результат считать беззнаковым числом, то флаг CF показывает условие переполнения (перенос или заём), для знакового результата (в дополнительном коде) перенос или заём показывает флаг OF, а для BCD-результата перенос/заём показывает флаг AF. Флаг SF отражает знак знакового результата, флаг ZF отражает и беззнаковый, и знаковый нулевой результат.

В длинной целочисленной арифметике флаг CF используется совместно с инструкциями сложения с переносом (ADC) и вычитания с заёмом (SBB) для распространения переноса или заёма из одного вычисляемого разряда длинного числа в другой.

Инструкции условного перехода Jcc (переход по условию cc — например, JNZ для перехода, если результат не ноль), SETcc (установить значение байта-результата в зависимости от условия cc), LOOPcc (организация цикла) и CMOVcc (условное копирование) используют один или несколько флагов состояния для проверки условия. Например, инструкция перехода JLE (jump if less or equal — переход, если «меньше или равен», ≤) проверяет условие «ZF=1 или SF ≠ OF».

Флаг PF был введён для совместимости с другими микропроцессорными архитектурами и по прямому назначению используется редко. Более распространено его использование совместно с остальными флагами состояния в арифметике с плавающей запятой[3]: инструкции сравнения (FCOM, FCOMP и т. п.) в математическом сопроцессоре устанавливают в нём флаги-условия C0, C1, C2 и C3 и эти флаги можно скопировать в регистр флагов. Для этого рекомендуется использовать инструкцию FSTSW AX для сохранения слова состояния сопроцессора в регистре AX и инструкцию SAHF для последующего копирования содержимого регистра AH в младшие 8 битов регистра флагов[4], при этом C0 попадает во флаг CF, C2 — в PF, а C3 — в ZF. Флаг C2 устанавливается, например, в случае несравнимых аргументов (NaN или неподдерживаемый формат) в инструкции сравнения FUCOM.

Управляющий флаг

Флаг направления (DF, бит 10 в регистре флагов) управляет строковыми инструкциями (MOVS, CMPS, SCAS, LODS и STOS): установка флага заставляет уменьшать адреса (обрабатывать строки от старших адресов к младшим), обнуление заставляет адреса увеличивать. Инструкции STD и CLD соответственно устанавливают и обнуляют флаг DF.

Системные флаги и поле IOPL

Системные флаги и поле IOPL управляют операционной средой и не предназначены для использования в прикладных программах.

  • IF — обнуление этого флага запрещает отвечать на маскируемые запросы на прерывание.
  • TF — установка этого флага разрешает пошаговый режим отладки, когда после каждой выполненной инструкции происходит прерывание программы и вызов специального обработчика прерывания (см. также: Int3).
  • IOPL — показывает уровень приоритета ввода-вывода исполняемой программы или задачи: чтобы программа или задача могла выполнять инструкции ввода-вывода или менять флаг IF, её текущий уровень приоритета (CPL) должен быть ≤ IOPL.
  • NT — этот флаг устанавливается, когда текущая задача «вложена» в другую, прерванную задачу, и сегмент состояния TSS текущей задачи обеспечивает обратную связь с TSS предыдущей задачи. Флаг NT проверяется инструкцией IRET для определения типа возврата — межзадачного или внутризадачного.
  • RF — флаг маскирования ошибок отладки.
  • AC — установка этого флага вместо с битом AM в регистре CR0 включает контроль выравнивания операндов при обращениях к памяти — обращение к невыравненному операнду вызывает исключительную ситуацию.
  • VIF — виртуальная копия флага IF; используется совместно с флагом VIP.
  • VIP — устанавливается для указания наличия отложенного прерывания; используется совместно с флагом VIF.
  • ID — возможность программно изменить этот флаг в регистре флагов указывает на поддержку инструкции CPUID.[2]

Идентификация процессора

В поздних версиях процессора 80486 появилась инструкция CPUID, позволяющая идентифицировать процессор, на котором работает программа. В более ранних процессорах для идентификации нужно анализировать особенности поведения инструкций и, в том числе, регистра флагов.

К примеру, в процессорах 8086 и 80186 биты 12-15 регистра флагов всегда установлены, в процессорах 80286 и новее биты 12-14 содержат поле IOPL и флаг NT и в реальном режиме всегда сброшены. Это позволяет в 16-битном коде различать процессоры 808x/8018x, 80286 и 80386 (и новее):

Также, флаг AC (бит 18), введённый в 80486, всегда сброшен в 80386, что и позволяет различить эти процессоры:

Аналогично, в старых моделях 80486, где инструкция CPUID ещё не введена, флаг ID (бит 21) всегда сброшен, что позволяет идентифицировать процессоры 80386 и старые модели 80486:

См. также

Напишите отзыв о статье "Регистр флагов"

Примечания

  1. 3.4.3. EFLAGS Register // The IA-32 Intel Architecture Software Developer’s Manual. — Intel, 2004. — Т. 1: [developer.intel.com/Assets/PDF/manual/253665.pdf Basic Architecture]. Order number: 253665-013
  2. 1 2 Инструкция CPUID была добавлена в поздних версиях процессора 80486 и процессоре Pentium. См.: [www.intel.com/software/products/documentation/vlin/mergedprojects/analyzer_ec/mergedprojects/reference_olh/mergedprojects/instructions/instruct32_hh/vc46.htm CPUID — CPU Identification] // The IA-32 Intel Architecture Software Developer’s Manual. — Intel, 2004. — Т. 2A: [developer.intel.com/Assets/PDF/manual/253666.pdf Instruction Set Reference, A-M]. Order number: 253666-013
  3. 8.1.3. Branching and Conditional Moves on Condition Codes // The IA-32 Intel Architecture Software Developer’s Manual. — Intel, 2004. — Т. 1: Basic Architecture. Order number: 253665-013
  4. В архитектуре P6 были введены инструкции FCOMI, FCOMIP и т. п., которые в результате сравнения устанавливают флаги в регистре флагов напрямую. Ранее это было невозможно, поскольку сопроцессор реализовывался отдельной микросхемой, и только начиная с 80486DX сопроцессор начали встраивать в процессор.

Отрывок, характеризующий Регистр флагов

В императорском лагере, близ Можайска, 6 го сентября, 1812 года».
Диспозиция эта, весьма неясно и спутанно написанная, – ежели позволить себе без религиозного ужаса к гениальности Наполеона относиться к распоряжениям его, – заключала в себе четыре пункта – четыре распоряжения. Ни одно из этих распоряжений не могло быть и не было исполнено.
В диспозиции сказано, первое: чтобы устроенные на выбранном Наполеоном месте батареи с имеющими выравняться с ними орудиями Пернетти и Фуше, всего сто два орудия, открыли огонь и засыпали русские флеши и редут снарядами. Это не могло быть сделано, так как с назначенных Наполеоном мест снаряды не долетали до русских работ, и эти сто два орудия стреляли по пустому до тех пор, пока ближайший начальник, противно приказанию Наполеона, не выдвинул их вперед.
Второе распоряжение состояло в том, чтобы Понятовский, направясь на деревню в лес, обошел левое крыло русских. Это не могло быть и не было сделано потому, что Понятовский, направясь на деревню в лес, встретил там загораживающего ему дорогу Тучкова и не мог обойти и не обошел русской позиции.
Третье распоряжение: Генерал Компан двинется в лес, чтоб овладеть первым укреплением. Дивизия Компана не овладела первым укреплением, а была отбита, потому что, выходя из леса, она должна была строиться под картечным огнем, чего не знал Наполеон.
Четвертое: Вице король овладеет деревнею (Бородиным) и перейдет по своим трем мостам, следуя на одной высоте с дивизиями Марана и Фриана (о которых не сказано: куда и когда они будут двигаться), которые под его предводительством направятся к редуту и войдут в линию с прочими войсками.
Сколько можно понять – если не из бестолкового периода этого, то из тех попыток, которые деланы были вице королем исполнить данные ему приказания, – он должен был двинуться через Бородино слева на редут, дивизии же Морана и Фриана должны были двинуться одновременно с фронта.
Все это, так же как и другие пункты диспозиции, не было и не могло быть исполнено. Пройдя Бородино, вице король был отбит на Колоче и не мог пройти дальше; дивизии же Морана и Фриана не взяли редута, а были отбиты, и редут уже в конце сражения был захвачен кавалерией (вероятно, непредвиденное дело для Наполеона и неслыханное). Итак, ни одно из распоряжений диспозиции не было и не могло быть исполнено. Но в диспозиции сказано, что по вступлении таким образом в бой будут даны приказания, соответственные действиям неприятеля, и потому могло бы казаться, что во время сражения будут сделаны Наполеоном все нужные распоряжения; но этого не было и не могло быть потому, что во все время сражения Наполеон находился так далеко от него, что (как это и оказалось впоследствии) ход сражения ему не мог быть известен и ни одно распоряжение его во время сражения не могло быть исполнено.


Многие историки говорят, что Бородинское сражение не выиграно французами потому, что у Наполеона был насморк, что ежели бы у него не было насморка, то распоряжения его до и во время сражения были бы еще гениальнее, и Россия бы погибла, et la face du monde eut ete changee. [и облик мира изменился бы.] Для историков, признающих то, что Россия образовалась по воле одного человека – Петра Великого, и Франция из республики сложилась в империю, и французские войска пошли в Россию по воле одного человека – Наполеона, такое рассуждение, что Россия осталась могущественна потому, что у Наполеона был большой насморк 26 го числа, такое рассуждение для таких историков неизбежно последовательно.
Ежели от воли Наполеона зависело дать или не дать Бородинское сражение и от его воли зависело сделать такое или другое распоряжение, то очевидно, что насморк, имевший влияние на проявление его воли, мог быть причиной спасения России и что поэтому тот камердинер, который забыл подать Наполеону 24 го числа непромокаемые сапоги, был спасителем России. На этом пути мысли вывод этот несомненен, – так же несомненен, как тот вывод, который, шутя (сам не зная над чем), делал Вольтер, говоря, что Варфоломеевская ночь произошла от расстройства желудка Карла IX. Но для людей, не допускающих того, чтобы Россия образовалась по воле одного человека – Петра I, и чтобы Французская империя сложилась и война с Россией началась по воле одного человека – Наполеона, рассуждение это не только представляется неверным, неразумным, но и противным всему существу человеческому. На вопрос о том, что составляет причину исторических событий, представляется другой ответ, заключающийся в том, что ход мировых событий предопределен свыше, зависит от совпадения всех произволов людей, участвующих в этих событиях, и что влияние Наполеонов на ход этих событий есть только внешнее и фиктивное.
Как ни странно кажется с первого взгляда предположение, что Варфоломеевская ночь, приказанье на которую отдано Карлом IX, произошла не по его воле, а что ему только казалось, что он велел это сделать, и что Бородинское побоище восьмидесяти тысяч человек произошло не по воле Наполеона (несмотря на то, что он отдавал приказания о начале и ходе сражения), а что ему казалось только, что он это велел, – как ни странно кажется это предположение, но человеческое достоинство, говорящее мне, что всякий из нас ежели не больше, то никак не меньше человек, чем великий Наполеон, велит допустить это решение вопроса, и исторические исследования обильно подтверждают это предположение.
В Бородинском сражении Наполеон ни в кого не стрелял и никого не убил. Все это делали солдаты. Стало быть, не он убивал людей.
Солдаты французской армии шли убивать русских солдат в Бородинском сражении не вследствие приказания Наполеона, но по собственному желанию. Вся армия: французы, итальянцы, немцы, поляки – голодные, оборванные и измученные походом, – в виду армии, загораживавшей от них Москву, чувствовали, что le vin est tire et qu'il faut le boire. [вино откупорено и надо выпить его.] Ежели бы Наполеон запретил им теперь драться с русскими, они бы его убили и пошли бы драться с русскими, потому что это было им необходимо.
Когда они слушали приказ Наполеона, представлявшего им за их увечья и смерть в утешение слова потомства о том, что и они были в битве под Москвою, они кричали «Vive l'Empereur!» точно так же, как они кричали «Vive l'Empereur!» при виде изображения мальчика, протыкающего земной шар палочкой от бильбоке; точно так же, как бы они кричали «Vive l'Empereur!» при всякой бессмыслице, которую бы им сказали. Им ничего больше не оставалось делать, как кричать «Vive l'Empereur!» и идти драться, чтобы найти пищу и отдых победителей в Москве. Стало быть, не вследствие приказания Наполеона они убивали себе подобных.
И не Наполеон распоряжался ходом сраженья, потому что из диспозиции его ничего не было исполнено и во время сражения он не знал про то, что происходило впереди его. Стало быть, и то, каким образом эти люди убивали друг друга, происходило не по воле Наполеона, а шло независимо от него, по воле сотен тысяч людей, участвовавших в общем деле. Наполеону казалось только, что все дело происходило по воле его. И потому вопрос о том, был ли или не был у Наполеона насморк, не имеет для истории большего интереса, чем вопрос о насморке последнего фурштатского солдата.
Тем более 26 го августа насморк Наполеона не имел значения, что показания писателей о том, будто вследствие насморка Наполеона его диспозиция и распоряжения во время сражения были не так хороши, как прежние, – совершенно несправедливы.
Выписанная здесь диспозиция нисколько не была хуже, а даже лучше всех прежних диспозиций, по которым выигрывались сражения. Мнимые распоряжения во время сражения были тоже не хуже прежних, а точно такие же, как и всегда. Но диспозиция и распоряжения эти кажутся только хуже прежних потому, что Бородинское сражение было первое, которого не выиграл Наполеон. Все самые прекрасные и глубокомысленные диспозиции и распоряжения кажутся очень дурными, и каждый ученый военный с значительным видом критикует их, когда сражение по ним не выиграно, и самью плохие диспозиции и распоряжения кажутся очень хорошими, и серьезные люди в целых томах доказывают достоинства плохих распоряжений, когда по ним выиграно сражение.
Диспозиция, составленная Вейротером в Аустерлицком сражении, была образец совершенства в сочинениях этого рода, но ее все таки осудили, осудили за ее совершенство, за слишком большую подробность.
Наполеон в Бородинском сражении исполнял свое дело представителя власти так же хорошо, и еще лучше, чем в других сражениях. Он не сделал ничего вредного для хода сражения; он склонялся на мнения более благоразумные; он не путал, не противоречил сам себе, не испугался и не убежал с поля сражения, а с своим большим тактом и опытом войны спокойно и достойно исполнял свою роль кажущегося начальствованья.


Вернувшись после второй озабоченной поездки по линии, Наполеон сказал:
– Шахматы поставлены, игра начнется завтра.
Велев подать себе пуншу и призвав Боссе, он начал с ним разговор о Париже, о некоторых изменениях, которые он намерен был сделать в maison de l'imperatrice [в придворном штате императрицы], удивляя префекта своею памятливостью ко всем мелким подробностям придворных отношений.
Он интересовался пустяками, шутил о любви к путешествиям Боссе и небрежно болтал так, как это делает знаменитый, уверенный и знающий свое дело оператор, в то время как он засучивает рукава и надевает фартук, а больного привязывают к койке: «Дело все в моих руках и в голове, ясно и определенно. Когда надо будет приступить к делу, я сделаю его, как никто другой, а теперь могу шутить, и чем больше я шучу и спокоен, тем больше вы должны быть уверены, спокойны и удивлены моему гению».
Окончив свой второй стакан пунша, Наполеон пошел отдохнуть пред серьезным делом, которое, как ему казалось, предстояло ему назавтра.
Он так интересовался этим предстоящим ему делом, что не мог спать и, несмотря на усилившийся от вечерней сырости насморк, в три часа ночи, громко сморкаясь, вышел в большое отделение палатки. Он спросил о том, не ушли ли русские? Ему отвечали, что неприятельские огни всё на тех же местах. Он одобрительно кивнул головой.
Дежурный адъютант вошел в палатку.
– Eh bien, Rapp, croyez vous, que nous ferons do bonnes affaires aujourd'hui? [Ну, Рапп, как вы думаете: хороши ли будут нынче наши дела?] – обратился он к нему.
– Sans aucun doute, Sire, [Без всякого сомнения, государь,] – отвечал Рапп.
Наполеон посмотрел на него.
– Vous rappelez vous, Sire, ce que vous m'avez fait l'honneur de dire a Smolensk, – сказал Рапп, – le vin est tire, il faut le boire. [Вы помните ли, сударь, те слова, которые вы изволили сказать мне в Смоленске, вино откупорено, надо его пить.]
Наполеон нахмурился и долго молча сидел, опустив голову на руку.
– Cette pauvre armee, – сказал он вдруг, – elle a bien diminue depuis Smolensk. La fortune est une franche courtisane, Rapp; je le disais toujours, et je commence a l'eprouver. Mais la garde, Rapp, la garde est intacte? [Бедная армия! она очень уменьшилась от Смоленска. Фортуна настоящая распутница, Рапп. Я всегда это говорил и начинаю испытывать. Но гвардия, Рапп, гвардия цела?] – вопросительно сказал он.
– Oui, Sire, [Да, государь.] – отвечал Рапп.
Наполеон взял пастильку, положил ее в рот и посмотрел на часы. Спать ему не хотелось, до утра было еще далеко; а чтобы убить время, распоряжений никаких нельзя уже было делать, потому что все были сделаны и приводились теперь в исполнение.
– A t on distribue les biscuits et le riz aux regiments de la garde? [Роздали ли сухари и рис гвардейцам?] – строго спросил Наполеон.