Fast FLAGS Save/Restore

There’s a nifty trick for saving and restoring the flags register on x86 and x86_64 that I ran across in DyninstAPI while working on my research. I can’t find it anywhere else that describes it with a quick Google search, so I figured I’d post it here.

WARNING: This is pretty technical.

Any x86 assembly programmer is aware of the PUSHF/POPF instructions. They save and restore the FLAGS register to the top of the stack, respectively. When inserting instrumentation, you will want to do this around every bit of code you insert so as not to perturb the original program. However, this can become quite expensive in terms of CPU time.

Luckily there is a faster alternative if you only care about saving a specific subset of commonly-used flags, specifically OF (overflow), SF (sign), ZF (zero), AF (auxiliary), PF (parity), and CF (carry). This alternative uses the LAHF and SAHF instructions to load and save the flags to AH (the high-order 8 bytes of AX); it also uses SETO to save the overflow bit and an additional trick (described below) to restore it.

Here is the saving sequence:

9f          lahf               ; save lower-order flags
0f 90 c0    seto %al           ; save OF
86 c4       xchg %al, %ah
50          push %eax

And here is the restoring sequence:

58          pop %eax
86 c4       xchg %al, %ah
80 c0 7f    add 0x7f, %al      ; restore OF
9e          sahf               ; restore lower-order flags

The XCHG instructions aren’t strictly necessary unless you want the saved values to reflect the correct byte order of the original FLAGS register. If you’re just saving and restoring the flags around a bit of code and don’t plan to modify those stored flags yourself, you don’t care what byte order they’re saved in.

The OF restore is the only part of this that isn’t entirely straightforward: basically, it performs an in-place 8-bit addition that is designed to overflow only if the overflow flag was set in the EAX-stored value. The addition won’t modify the higher bytes of EAX even if the overflow occurs, so this is safe.

The only other caveat is that these excerpts assume that EAX can be clobbered. If you can’t make this assumption, you can just add an extra push/pop of EAX around these excerpts to save and restore that register as well.

I hope this is helpful to someone besides myself. :)

This entry was posted in Software/Comp. Sci.. Bookmark the permalink.

2 Responses to Fast FLAGS Save/Restore

  1. Nick says:

    Wow, this is actually very helpful for some things I’m working on right now. Good stuff Mike.

  2. Mike says:

    Of course–glad to be of help!

    :P

Comments are closed.