I want to move the zero flag set as the result of a comparison, e.g. "cmp rax,rbx", into a register. I know I can use one of PUSHF/PUSHFD/PUSHFQ to push the flags onto the stack, but now I want to move just the zero flag from the stack to a register.
According to https://www.felixcloutier.com/x86/pushf:pushfd:pushfq, it "Decrements the stack pointer by 4 (if the current operand-size attribute is 32) and pushes the entire contents of the EFLAGS register onto the stack." But that doesn't tell me the order they are pushed and how to access the zero flag.
According to the Intel Software Developers Manual (June 2023), section 7.3.13.2, the zero flag is #6 from the base at zero. (Also Wikipedia). So from that I would guess that mov al,[rsp+6] would do it. But I need to be sure because they are all just booleans -- I may grab the wrong boolean.
I'm in 64-bit mode, so I would be addressing the RFLAGS register. Section 7.3.1.4 of the manual says, "PUSHF and POPF behave the same in 64-bit mode as in non-64-bit mode. PUSHFD always pushes 64-bit RFLAGS onto the stack (with the RF and VM flags read as clear). POPFD always pops a 64-bit value from the top of the stack and loads the lower 32 bits into RFLAGS. It then zero extends the upper bits of RFLAGS."
Finally, what's the difference between PUSHFD and PUSHFQ? Double word and quadword, but which should I use in 64-bit mode?
This MASM example extracts the ZF (bit #6) from the RFLAGS register using the very inefficient
PUSHFQ/POPmethod and stores it in thercxregister. As noted in the comments below, there are much more efficient alternatives.Here's a brief overview of the first 16-bit flags register: