The flags register is a 16-bit register in which nine bits have a meaning. Six are status flags: arithmetic and logic instructions set or clear them to describe their result, and conditional jumps test them. Three are control flags that change how the CPU behaves. The other bits hold no flag.
| Bit | Flag | Set (1) when |
|---|---|---|
| 0 | CF carry | an unsigned result carried out of, or borrowed into, the top bit; also the last bit shifted out |
| 2 | PF parity | the low byte of the result has an even number of 1 bits |
| 4 | AF auxiliary carry | a carry out of, or borrow into, bit 3 (used by the decimal adjust instructions) |
| 6 | ZF zero | the result is 0 |
| 7 | SF sign | the top bit of the result is 1 (negative if signed) |
| 8 | TF trap | control: INT 1 after each instruction (single step) |
| 9 | IF interrupt | control: maskable hardware interrupts are accepted |
| 10 | DF direction | control: string instructions count down instead of up |
| 11 | OF overflow | a signed result does not fit the destination |
MOV AL, 0FFhADD AL, 1 ; FFh + 1 = 100h: AL = 0, a carry outLAHF ; AH = SF ZF - AF - PF - CFMOV BL, AHMOV AL, BLAND AL, 1 ; CF, bit 0ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hMOV AL, BLMOV CL, 6SHR AL, CLAND AL, 1 ; ZF, bit 6ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hMOV AL, BLMOV CL, 7SHR AL, CL ; SF, bit 7ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21h
Who changes what
| Instructions | Flags |
|---|---|
| MOV XCHG LEA PUSH POP, jumps, LOOP | none |
| ADD ADC SUB SBB CMP NEG | OF SF ZF AF PF CF |
| INC DEC | OF SF ZF AF PF; CF unchanged |
| AND OR XOR TEST | SF ZF PF; CF = OF = 0 |
| MUL IMUL | CF OF; the others undefined |
| DIV IDIV | all undefined |
Signed and unsigned
The CPU does not know whether a byte is signed. It sets both CF (meaningful for unsigned numbers) and OF (meaningful for signed ones), and you pick the jump that matches your data: JB / JA read CF, JL / JG read SF and OF. FFh + 1 sets CF, since 255 + 1 does not fit; 7Fh + 1 sets OF, since 127 + 1 is not a signed byte.
Setting flags directly
CLC / STC / CMC change CF, CLD / STD change DF, CLI / STI change IF. LAHF / SAHF copy the low byte to and from AH; PUSHF / POPF save and load all of them, and are the only way to change TF.
Later CPUs
The 80286 uses bits 12-14 for the I/O privilege level and the nested task flag. The 80386 widens the register to 32-bit EFLAGS with the resume and virtual-8086 flags; later models add more.