FLAGS register: Difference between revisions

From HandWiki
(change)
 
(add)
 
Line 1: Line 1:
{{Short description|Status register of x86 architecture}}
{{Short description|Status register of x86 architecture}}
This is an introduction to flags.
The '''FLAGS''' [[Processor register|register]] is the [[Status register|status register]] that contains the current state of an x86 CPU. The size and meanings of the flag bits are architecture dependent. It usually reflects the result of arithmetic operations as well as information about restrictions placed on the CPU operation at the current time. Some of those restrictions may include preventing some interrupts from triggering, prohibition of execution of a class of "privileged" instructions. Additional status flags may bypass memory mapping and define what action the CPU should take on arithmetic overflow.
The '''FLAGS''' [[Processor register|register]] is the [[Status register|status register]] that contains the current state of an x86 CPU. The size and meanings of the flag bits are architecture dependent. It usually reflects the result of arithmetic operations as well as information about restrictions placed on the CPU operation at the current time. Some of those restrictions may include preventing some interrupts from triggering, prohibition of execution of a class of "privileged" instructions. Additional status flags may bypass memory mapping and define what action the CPU should take on arithmetic overflow.


The carry, parity, auxiliary carry (or [[Half-carry flag|half carry]]), zero and sign flags are included in many architectures.
The carry, parity, auxiliary carry (or [[Half-carry flag|half carry]]), zero and sign flags are included in many architectures (many modern (RISC) architectures do not have flags, such as carry, and even if they do use flags, then half carry is rare, since BCD math is no longer common, and it even has limited support on [[Long mode|long mode]] on [[X86-64|x86-64]]).


In the i286 architecture, the register is [[16-bit|16 bits]] wide. Its successors, the '''EFLAGS''' and '''RFLAGS''' registers, are [[32-bit|32 bits]] and 64 bits wide, respectively. The wider registers retain compatibility with their smaller predecessors.
In the i286 architecture, the register is [[16-bit|16 bits]] wide. Its successors, the '''EFLAGS''' and '''RFLAGS''' registers (in modern [[X86-64|x86-64]]), are [[32-bit|32 bits]] and 64 bits wide, respectively. The wider registers retain compatibility with their smaller predecessors.


==FLAGS==
==FLAGS==
{| class="wikitable" style="text-align:center"
{| class="wikitable" style="text-align:center"
|-
|-
! colspan="7" style="background:#cfcfcf;" | Intel x86 FLAGS register<ref>{{cite book|title=Intel 64 and IA-32 Architectures Software Developer's Manual|url=http://download.intel.com/products/processor/manual/253665.pdf#page=93|volume=1|date=May 2012|pages=3–21}}</ref>
! colspan="7" style="background:#cfcfcf;" | Intel x86 FLAGS register<ref>{{cite book|title=Intel 64 and IA-32 Architectures Software Developer's Manual|url=https://download.intel.com/products/processor/manual/253665.pdf#page=93|volume=1|date=May 2012|pages=3–21}}</ref>
|-
|-
! Bit # !! Mask !! Abbreviation !! Description !! Category !! =1 !! =0
! Bit # !! Mask !! Abbreviation !! Description !! Category !! =1 !! =0
Line 18: Line 16:
! colspan="7" style="background:#efefef" | FLAGS
! colspan="7" style="background:#efefef" | FLAGS
|-
|-
| 0 || 0x0001 || CF || [[Carry flag]] || Status || CY(Carry) || NC(No Carry)
| 0 || 0x0001 || CF || [[Carry flag]] || Status || CY (Carry) || NC (No Carry)
|-
|-
| 1 || 0x0002 || {{sdash}} || Reserved, always 1 in '''EFLAGS''' <ref>{{cite book|title=Intel 64 and IA-32 Architectures Software Developer’s Manual|url=https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf#page=78|volume=1|date=Dec 2016|pages=78}}</ref><ref name=r8085>{{Cite web|url=http://www.righto.com/2013/02/looking-at-silicon-to-understanding.html|title=Silicon reverse engineering: The 8085's undocumented flags|website=www.righto.com|access-date=2018-10-21}}</ref> || {{sdash}}
| 1 || 0x0002 || {{sdash}} || Reserved, always 1 in '''EFLAGS'''<ref>{{cite book|title=Intel 64 and IA-32 Architectures Software Developer's Manual|url=https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf#page=78|volume=1|date=Dec 2016|pages=78}}</ref><ref name=r8085>{{Cite web|url=https://www.righto.com/2013/02/looking-at-silicon-to-understanding.html|title=Silicon reverse engineering: The 8085's undocumented flags|website=www.righto.com|access-date=2018-10-21}}</ref> || {{sdash}}
|-
|-
| 2 || 0x0004 || PF || [[Parity flag]] || Status || PE(Parity Even) || PO(Parity Odd)
| 2 || 0x0004 || PF || [[Parity flag]] || Status || PE (Parity Even) || PO (Parity Odd)
|-
|-
| 3 || 0x0008 || {{sdash}} || Reserved<ref name=r8085/> || {{sdash}}
| 3 || 0x0008 || {{sdash}} || Reserved<ref name=r8085/> || {{sdash}}
|-
|-
| 4 || 0x0010 || AF || [[Half-carry flag#The Auxiliary Carry Flag in x86|Auxiliary Carry flag]]<ref>{{cite book |title=Intel 64 and IA-32 Architectures Software Developer’s Manual, Vol. 1 |date=Dec 2022 |page=3-16|url=https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html}}</ref> || Status || AC(Auxiliary Carry) || NA(No Auxiliary Carry)
| 4 || 0x0010 || AF || [[Half-carry flag#The Auxiliary Carry Flag in x86|Auxiliary Carry flag]]<ref>{{cite book |title=Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 1 |date=Dec 2022 |pages=3–16|url=https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html}}</ref> || Status || AC (Auxiliary Carry) || NA (No Auxiliary Carry)
|-
|-
| 5 || 0x0020 || {{sdash}} || Reserved<ref name=r8085/> || {{sdash}}
| 5 || 0x0020 || {{sdash}} || Reserved<ref name=r8085/> || {{sdash}}
|-
|-
| 6 || 0x0040 || ZF || [[Zero flag]] || Status || ZR(Zero) || NZ(Not Zero)
| 6 || 0x0040 || ZF || [[Zero flag]] || Status || ZR (Zero) || NZ (Not Zero)
|-
|-
| 7 || 0x0080 || SF || Sign flag || Status || NG(Negative) || PL(Positive)
| 7 || 0x0080 || SF || Sign flag || Status || NG (Negative) || PL (Positive)
|-
|-
| 8 || 0x0100 || TF || [[Trap flag]] (single step) || Control
| 8 || 0x0100 || TF || [[Trap flag]] (single step) || Control
|-
|-
| 9 || 0x0200 || IF || Interrupt enable flag || Control || EI(Enable Interrupt) || DI(Disable Interrupt)
| 9 || 0x0200 || IF || Interrupt enable flag || Control || EI (Enable Interrupt) || DI (Disable Interrupt)
|-
|-
| 10 || 0x0400 || DF || [[Direction flag]] || Control || DN(Down) || UP(Up)
| 10 || 0x0400 || DF || [[Direction flag]] || Control || DN (Down) || UP (Up)
|-
|-
| 11 || 0x0800 || OF || [[Overflow flag]] || Status || OV(Overflow) || NV(Not Overflow)
| 11 || 0x0800 || OF || [[Overflow flag]] || Status || OV (Overflow) || NV (Not Overflow)
|-
|-
| 12-13 || 0x3000 || IOPL || [[IOPL|I/O privilege level]] (286+ only), <br>always all-1s on 8086 and 186 || System
| 12–13 || 0x3000 || IOPL || [[IOPL|I/O privilege level]] (286+ only), <br>always all-1s on 8086 and 186 || System
|-
|-
| 14 || 0x4000 || NT || Nested task flag (286+ only), <br>always 1 on 8086 and 186 || System
| 14 || 0x4000 || NT || Nested task flag (286+ only), <br>always 1 on 8086 and 186 || System
Line 62: Line 60:
| 21 || 0x0020&nbsp;0000 || ID || Able to use [[CPUID]] instruction (Pentium+) || System
| 21 || 0x0020&nbsp;0000 || ID || Able to use [[CPUID]] instruction (Pentium+) || System
|-
|-
| 22-29 || 0x3FC0&nbsp;0000 || {{sdash}} || Reserved || {{sdash}}
| 22–29 || 0x3FC0&nbsp;0000 || {{sdash}} || Reserved || {{sdash}}
|-
|-
| 30 || 0x4000&nbsp;0000 || (none) || AES key schedule loaded flag<ref>VIA, [https://web.archive.org/web/20100526054140/http://linux.via.com.tw/support/beginDownload.action?eleid=181&fid=261 PadLock Programming Guide], v1.66, Aug 4, 2005, pp. 7-8. Archived from [http://linux.via.com.tw/support/beginDownload.action?eleid=181&fid=261 the original] on May 26, 2010.</ref><br>(CPUs with [[VIA PadLock]] only) || System  
| 30 || 0x4000&nbsp;0000 || (none) || AES key schedule loaded flag<ref>VIA, [https://web.archive.org/web/20100526054140/http://linux.via.com.tw/support/beginDownload.action?eleid=181&fid=261 PadLock Programming Guide], v1.66, Aug 4, 2005, pp. 7-8. Archived from [https://linux.via.com.tw/support/beginDownload.action?eleid=181&fid=261 the original] on May 26, 2010.</ref><br>(CPUs with [[VIA PadLock]] only) || System  
|-
|-
| 31 || 0x8000&nbsp;0000 || AI || Alternate Instruction Set enabled<br/>([[Engineering:VIA C3|VIA C5XL]] processors only)<ref>VIA, [http://www.bitsavers.org/components/viaTechnologies/C3-ais-appnote.pdf VIA C3 Processor Alternate Instruction Set Application Note], version 0.24, 2002 - see figure 2 on page 12 and chapter 4 on page 21 for details on the EFLAGS.AI flag.</ref>  || System
| 31 || 0x8000&nbsp;0000 || AI || Alternate Instruction Set enabled<br/>([[Engineering:VIA C3|VIA C5XL]] processors only)<ref>VIA, [https://www.bitsavers.org/components/viaTechnologies/C3-ais-appnote.pdf VIA C3 Processor Alternate Instruction Set Application Note], version 0.24, 2002 - see figure 2 on page 12 and chapter 4 on page 21 for details on the EFLAGS.AI flag.</ref>  || System
|-
|-
! colspan="7" style="background:#efefef" | RFLAGS
! colspan="7" style="background:#efefef" | RFLAGS
Line 78: Line 76:


FLAGS registers can be moved from or to the stack. This is part of the job of saving and restoring CPU context, against a routine such as an interrupt service routine whose changes to registers should not be seen by the calling code. Here are the relevant instructions:
FLAGS registers can be moved from or to the stack. This is part of the job of saving and restoring CPU context, against a routine such as an interrupt service routine whose changes to registers should not be seen by the calling code. Here are the relevant instructions:
*The PUSHF and POPF instructions transfer the 16-bit FLAGS register.
* The PUSHF and POPF instructions transfer the 16-bit FLAGS register.
*PUSHFD/POPFD (introduced with the [[Engineering:I386|i386]] architecture) transfer the 32-bit double register EFLAGS.
* PUSHFD/POPFD (introduced with the [[Engineering:I386|i386]] architecture) transfer the 32-bit double register EFLAGS.
*PUSHFQ/POPFQ (introduced with the x64 architecture) transfer the 64-bit quadword register RFLAGS.
* PUSHFQ/POPFQ (introduced with the [[X86-64|x86-64]] architecture) transfer the 64-bit quadword register RFLAGS.
In 64-bit mode, PUSHF/POPF and PUSHFQ/POPFQ are available but PUSHFD/POPFD are not.<ref>{{cite book|title=Intel 64 and IA-32 Architectures Software Developer’s Manual|url=http://download.intel.com/products/processor/manual/253667.pdf#page=351|volume=2B|date=May 2012}}</ref>{{Rp|4-349,4-432}}
In 64-bit mode, PUSHF/POPF and PUSHFQ/POPFQ are available but PUSHFD/POPFD are not.<ref>{{cite book|title=Intel 64 and IA-32 Architectures Software Developer's Manual|url=https://download.intel.com/products/processor/manual/253667.pdf#page=351|volume=2B|date=May 2012}}</ref>{{Rp|4-349,4-432}}


The lower 8 bits of the FLAGS register is also open to direct load/store manipulation by SAHF and LAHF (load/store AH into flags).
The lower 8 bits of the FLAGS register is also open to direct load/store manipulation by SAHF and LAHF (load/store AH into flags).
Line 88: Line 86:
The ability to push and pop FLAGS registers lets a program manipulate information in the FLAGS in ways for which machine-language instructions do not exist. For example, the <code>cld</code> and <code>std</code> instructions clear and set the direction flag (DF), respectively; but there is no instruction to complement DF. This can be achieved with the following assembly code:
The ability to push and pop FLAGS registers lets a program manipulate information in the FLAGS in ways for which machine-language instructions do not exist. For example, the <code>cld</code> and <code>std</code> instructions clear and set the direction flag (DF), respectively; but there is no instruction to complement DF. This can be achieved with the following assembly code:


<source lang="nasm">
<syntaxhighlight lang="nasm">
               ; This is 8086 code, with 16-bit registers pushed onto the stack,
               ; This is 8086 code, with 16-bit registers pushed onto the stack,
               ; and the flags register is only 16 bits with this CPU.
               ; and the flags register is only 16 bits with this CPU.
Line 99: Line 97:
; Insert here the code that required the DF flag to be complemented
; Insert here the code that required the DF flag to be complemented
popf          ; Restore the original value of the FLAGS
popf          ; Restore the original value of the FLAGS
</source>
</syntaxhighlight>


By manipulating the FLAGS register, a program can determine the model of the installed processor. For example, the alignment flag can only be changed on the [[Engineering:Intel 80486|486]] and above. If the program tries to modify this flag and senses that the modification did not persist, the processor is earlier than the 486.
By manipulating the FLAGS register, a program can determine the model of the installed processor. For example, the alignment flag can only be changed on the [[Engineering:Intel 80486|486]] and above. If the program tries to modify this flag and senses that the modification did not persist, the processor is earlier than the 486.

Latest revision as of 23:22, 4 September 2025

Short description: Status register of x86 architecture

The FLAGS register is the status register that contains the current state of an x86 CPU. The size and meanings of the flag bits are architecture dependent. It usually reflects the result of arithmetic operations as well as information about restrictions placed on the CPU operation at the current time. Some of those restrictions may include preventing some interrupts from triggering, prohibition of execution of a class of "privileged" instructions. Additional status flags may bypass memory mapping and define what action the CPU should take on arithmetic overflow.

The carry, parity, auxiliary carry (or half carry), zero and sign flags are included in many architectures (many modern (RISC) architectures do not have flags, such as carry, and even if they do use flags, then half carry is rare, since BCD math is no longer common, and it even has limited support on long mode on x86-64).

In the i286 architecture, the register is 16 bits wide. Its successors, the EFLAGS and RFLAGS registers (in modern x86-64), are 32 bits and 64 bits wide, respectively. The wider registers retain compatibility with their smaller predecessors.

FLAGS

Intel x86 FLAGS register[1]
Bit # Mask Abbreviation Description Category =1 =0
FLAGS
0 0x0001 CF Carry flag Status CY (Carry) NC (No Carry)
1 0x0002 Reserved, always 1 in EFLAGS[2][3]
2 0x0004 PF Parity flag Status PE (Parity Even) PO (Parity Odd)
3 0x0008 Reserved[3]
4 0x0010 AF Auxiliary Carry flag[4] Status AC (Auxiliary Carry) NA (No Auxiliary Carry)
5 0x0020 Reserved[3]
6 0x0040 ZF Zero flag Status ZR (Zero) NZ (Not Zero)
7 0x0080 SF Sign flag Status NG (Negative) PL (Positive)
8 0x0100 TF Trap flag (single step) Control
9 0x0200 IF Interrupt enable flag Control EI (Enable Interrupt) DI (Disable Interrupt)
10 0x0400 DF Direction flag Control DN (Down) UP (Up)
11 0x0800 OF Overflow flag Status OV (Overflow) NV (Not Overflow)
12–13 0x3000 IOPL I/O privilege level (286+ only),
always all-1s on 8086 and 186
System
14 0x4000 NT Nested task flag (286+ only),
always 1 on 8086 and 186
System
15 0x8000 MD Mode flag (NEC V-series only),[5]
reserved on all Intel CPUs.
Always 1 on 8086/186, 0 on 286 and later.
Control (NEC only)
Native Mode
(186 compatible)
(NEC only)
Emulation Mode
(8080 compatible)
EFLAGS
16 0x0001 0000 RF Resume flag (386+ only) System
17 0x0002 0000 VM Virtual 8086 mode flag (386+ only) System
18 0x0004 0000 AC Alignment Check (486+, ring 3),
SMAP Access Check (Broadwell+, ring 0-2)
System
19 0x0008 0000 VIF Virtual interrupt flag (Pentium+) System
20 0x0010 0000 VIP Virtual interrupt pending (Pentium+) System
21 0x0020 0000 ID Able to use CPUID instruction (Pentium+) System
22–29 0x3FC0 0000 Reserved
30 0x4000 0000 (none) AES key schedule loaded flag[6]
(CPUs with VIA PadLock only)
System
31 0x8000 0000 AI Alternate Instruction Set enabled
(VIA C5XL processors only)[7]
System
RFLAGS
32‑63 0xFFFF FFFF…
…0000 0000
Reserved

Note: The mask column in the table is the AND bitmask (as hexadecimal value) to query the flag(s) within FLAGS register value.

Usage

All FLAGS registers contain the condition codes, flag bits that let the results of one machine-language instruction affect another instruction. Arithmetic and logical instructions set some or all of the flags, and conditional jump instructions take variable action based on the value of certain flags. For example, jz (Jump if Zero), jc (Jump if Carry), and jo (Jump if Overflow) depend on specific flags. Other conditional jumps test combinations of several flags.

FLAGS registers can be moved from or to the stack. This is part of the job of saving and restoring CPU context, against a routine such as an interrupt service routine whose changes to registers should not be seen by the calling code. Here are the relevant instructions:

  • The PUSHF and POPF instructions transfer the 16-bit FLAGS register.
  • PUSHFD/POPFD (introduced with the i386 architecture) transfer the 32-bit double register EFLAGS.
  • PUSHFQ/POPFQ (introduced with the x86-64 architecture) transfer the 64-bit quadword register RFLAGS.

In 64-bit mode, PUSHF/POPF and PUSHFQ/POPFQ are available but PUSHFD/POPFD are not.[8]:4-349,4-432

The lower 8 bits of the FLAGS register is also open to direct load/store manipulation by SAHF and LAHF (load/store AH into flags).

Example

The ability to push and pop FLAGS registers lets a program manipulate information in the FLAGS in ways for which machine-language instructions do not exist. For example, the cld and std instructions clear and set the direction flag (DF), respectively; but there is no instruction to complement DF. This can be achieved with the following assembly code:

; This is 8086 code, with 16-bit registers pushed onto the stack,
               ; and the flags register is only 16 bits with this CPU.
pushf          ; Use the stack to transfer the FLAGS
pop   ax       ; … into the AX register
push  ax       ; and copy them back onto the stack for storage
xor   ax, 400h ; Toggle (invert, ‘complement’) the DF only; other bits are unchanged
push  ax       ; Use the stack again to move the modified value
popf           ; … into the FLAGS register
; Insert here the code that required the DF flag to be complemented
popf          ; Restore the original value of the FLAGS

By manipulating the FLAGS register, a program can determine the model of the installed processor. For example, the alignment flag can only be changed on the 486 and above. If the program tries to modify this flag and senses that the modification did not persist, the processor is earlier than the 486.

Starting with the Intel Pentium, the CPUID instruction reports the processor model. However, the above method remains useful to distinguish between earlier models.

See also

References