PUSHF pushes the whole 16-bit flags register onto the stack, like a PUSH of a register (SP − 2). POPF pops a word into the flags register (SP + 2), so every flag, including TF, IF and DF, takes the value from that word. They are the only instructions that read or write all the flags at once, and POPF is the only ordinary way to set TF.

Prints 1.
STC ; CF = 1
PUSHF ; save the flags
CLC ; CF = 0
POPF ; CF = 1 again
MOV AL, 0
ADC AL, 0 ; AL = 0 + 0 + CF
ADD AL, '0' ; digit -> character
MOV DL, AL
MOV AH, 02h ; DOS: print DL
INT 21h

Uses

Keeping the caller's flags across a routine that changes them, for instance one that must preserve DF or IF. Changing a single flag that has no instruction of its own: push the flags, pop them into a register, change the bit, push it and pop it into the flags. A debugger sets TF (bit 8) this way so that the CPU raises INT 1 after the next instruction.

PUSHF
POP AX ; AX = flags
OR AX, 0100h ; set TF (bit 8)
PUSH AX
POPF ; single-step mode from here on

Telling the CPU apart

On the 8086 and 8088, bits 12 to 15 of the flags word always read as 1, whatever POPF tried to write. On the 80286 in real mode they always read as 0. Programs used this to detect the processor.

PUSHF
POP AX
AND AX, 0FFFh ; try to clear bits 12-15
PUSH AX
POPF
PUSHF
POP AX
AND AX, 0F000h
CMP AX, 0F000h ; still all set: an 8086 or 8088
JE CPU86

Pitfalls

POPF restores IF as well. A routine that does PUSHF / CLI / ... / POPF turns interrupts back on only if they were on before, which is usually what you want; a plain STI at the end would turn them on unconditionally. An interrupt pushes the flags itself, and IRET pops them, so an interrupt handler does not need PUSHF.

Later CPUs

The 80286 uses bits 12 to 14 for the I/O privilege level and nested task flag; in protected mode POPF may not change IF or IOPL without enough privilege. The 80386 adds PUSHFD / POPFD for the 32-bit EFLAGS.