1

I've done some browsing and it seems like the PF and AF are very rarely used, and for a beginner such as myself, can basically be ignored as they rarely if ever will come up. From what I've found it seems the use-cases are:

Except for obscure cases, can these two flags be all but ignored? Or is there ever a time when I should be reading these flags and making use of them?

Examples:

# AF (CF on 4th bit)
mov $0b1000, %eax
add $0b1000, %eax # [ AF ]


# PF (num 1's is a multiple of two)
inc %eax # [ PF ]
carl.hiass
  • 1,526
  • 1
  • 6
  • 26
  • Yes you can mostly ignore them, but note that `PF` is also used by `FCOMI` and friends. Of course x87 itself is pretty much obsolete by now. – Jester Sep 27 '20 at 00:03
  • 1
    @Jester: SSE2 / AVX scalar FP compares set FLAGS identically to `fcomi`, which in turn sets them identically to `fcom` / `fstw ax` / `sahf`. [Why do x86 FP compares set CF like unsigned integers, instead of using signed conditions?](https://stackoverflow.com/q/57188286). So yes, PF is still used by modern scalar FP-compare code. But not as a parity flag, just a historical accident (or really a design choice) that it lined up with PF instead of OF or SF or something. – Peter Cordes Sep 27 '20 at 00:44
  • And yes, agreed you can ignore them outside of that, especially in x86-64 where the ASCII instructions like AAA don't exist. In 32-bit mode there are occasional code-size optimization hacks you can use like using `das` as part of converting an integer to hex. ([Percent-Encode a String](https://codegolf.stackexchange.com/a/158304)). Although I'm not sure if that depends on AF or just on the over-10 behaviour. – Peter Cordes Sep 27 '20 at 01:18
  • Finally found details on the DAS trick for hex digits: I wrote up how it worked in a code-golf answer of mine ([Little Endian Number to String Conversion](https://codegolf.stackexchange.com/a/193842)) after peter ferrie suggested it. This is definitely not the "normal" way to do that, only just exploiting AF and DAS for unintended purposes because they're there. BCD or unpacked decimal are generally bad formats for extended precision, so normally you wouldn't be using it for the intended purpose, especially not in 64-bit mode when you need pushf / pop rax to read AF. – Peter Cordes Sep 27 '20 at 01:56

1 Answers1

2

Except for obscure cases ...

Depends on what you call "obscure":

The AF flag is used for BCD calculations which was supported by the early CPUs (in the case of x86: the 8088) mainly for being used in calculators:

Early CPUs did not have floating-point support (in the case of x86 CPUs you could add a separate x87 FPU which was more expensive than the computer itself), and BCD arithmetic was a simple method to perform floating-point calculations if both the input (from the keyboard) and the output (to the display) was given in decimal system.

I remember some special PASCAL dialect for physics calculations around the year 2000 using BCD arithmetic calculations for high-precision calculations.

The PF flag could be used for some cases of hardware access:

When sending a 7-bit data word with parity over some early RS-232 ports, you actually had to send an 8-bit word (without additional parity); the 8th bit was the parity that had to be calculated by the CPU. Using the PF flag calculating this bit is easy!

... in modern asm ...

Or is there ever a time when I should be reading these flags and making use of them?

As far as I know, the AF flag was not intended to be read at all even in early x86 CPUs:

The flag was only used as input to BCD operations (just like the CF flag is an input to the sbb and adc instructions); however, unlike the CF flag it was not intended to "read" AF directly (using a conditional jump operation).

So even early x86 programmers did not care about the AF flag but the flag was only used by the CPU in the "background" when BCD arithmetic was done.

Using modern operating systems (such as Linux and Windows) only device drivers access the hardware; and most modern hardware (for example RS-232 ports) is capable of calculating the parity in hardware.

So using the PF flag normally is also not necessary.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • 1
    You do sometimes want a horizontal XOR of something, e.g. for bit-matrix stuff where XOR is add-without-carry. If you don't have `popcnt`, then `mov edx, eax` / `shr eax, 16` / `xor eax, edx` / `xor al, ah` sets PF according to the horizontal-xor of all 32 bits of the original EAX. GCC I think does something like this for `__builtin_parity` [How to XOR all of the bits of a single number in C?](https://stackoverflow.com/q/38309952) – Peter Cordes Sep 27 '20 at 07:59
  • So yes it's pretty rare to use PF for anything other than floating-point compares (ucomisd and so on), but the use-case for actual numeric parity is not limited to serial-port device drivers. – Peter Cordes Sep 27 '20 at 08:00