问题
I am programming using the AT&T notation on the i386 architecture.
Is it possible to add two 8-bit numbers in order to set the Carry, Overflow, and Sign Flags to be set, using a single add
instruction?
I am thinking it is impossible to get this flag combination. In order for the S-flag to be set together with the O-flag, the most significant bits of both numbers would have to be 0 and the most significant bit of the result would have to be 1. That leaves us with no way to generate a carry from the addition of the most significant bits.
This is my first time asking a question on this site, so I apologize if I did anything wrong. Thanks in advance.
EDIT: I can ONLY use the following three instructions:
movb $_, %ah
movb $_,%al
addb %ah,%al
I have to modify the two underscores with decimal values.
EDIT: Out of CF, OF, SF, and ZF, I can only have CF, OF, and SF set. I cannot have the Carry Flag set.
(editor's note: That last sentence makes no sense. Is that a typo for Parity or Zero Flag, or maybe he means CF can't be set before the addb
? It's add
, not adc
, so it doesn't depend on the previous state of flags. Leaving this as an edit instead of requesting clarification in a comment because it's an old question that might not get a response. Please edit out this note if/when you fix that sentence about "cannot have the Carry Flag set", Shan.)
回答1:
It is impossible to set CF=SF=OF=1 with add ah, al
. A formal proof is going to be somewhat lengthy, but a simple exhaustive test confirms the impossibility of such a combination of flag states after an add
instruction.
You can use POPF(D)
to set an arbitrary combination of arithmetic flags. This instruction will pop a (d)word from the stack and write it into (E)FLAGS
.
Note that there are other, unrelated to arithmetic, flags in the flags register. You shouldn't generally modify them. So, you'd typically first read the value of the register (using PUSHF(D)
), modify that as necessary and then write back as outlined above.
回答2:
Edit: Using only add al,ah
or any other add
it is impossible.
You can do it by popping flags
/ eflags
into some register, then setting the flags you want with or
, pushing the register and popping it into flags.
For 16-bit code (NASM syntax):
pushf
pop ax
or ax,0x881
push ax
popf
For 32-bit code:
pushfd
pop eax
or eax,0x881
push eax
popfd
来源:https://stackoverflow.com/questions/15330169/is-it-possible-to-set-the-x86-flags-to-carry-sign-overflow-1-with-one-addition-i