是否可以通过一次添加insn将x86标志设置为Carry = Sign = Overflow = 1?

时间:2013-03-11 02:10:22

标签: assembly x86 flags

我正在使用i386架构上的AT& T表示法进行编程。

是否可以使用单个add指令添加两个8位数字以设置Carry,Overflow和Sign Flags?

我在想这个旗帜组合是不可能的。为了将S标志与O标志一起设置,两个数字的最高有效位必须为0,结果的最高有效位必须为1.这使我们无法通过添加最高有效位来生成进位。

这是我第一次在这个网站上提问,所以如果我做错了什么我会道歉。提前谢谢。

编辑:我只能使用以下三条说明:

movb $_, %ah
movb $_,%al 
addb %ah,%al

我必须用十进制值修改两个下划线。

编辑:在CF,OF,SF和ZF中,我只能设置CF,OF和SF。我不能设置进位标志。

(编者注:最后一句没有意义。这是Parity或Zero Flag的错字,或者他的意思是CF addb,而不是add,因此它不依赖于之前的标记状态。将此作为编辑而不是在评论中请求澄清,因为这是一个可能无法获得响应的旧问题。如果/当您修复关于“无法设置进位标志”的句子时,请编辑此注释。)

2 个答案:

答案 0 :(得分:4)

不可能add ah, al设置CF = SF = OF = 1。一个正式的证明有点冗长,但是一个简单的详尽测试证实了add指令后这种旗状态组合是不可能的。


您可以使用POPF(D)设置算术标志的任意组合。该指令将从堆栈中弹出一个(d)字,并将其写入(E)FLAGS

请注意,flags寄存器中还有其他与算术无关的标志。你通常不应该修改它们。因此,您通常首先读取寄存器的值(使用PUSHF(D)),根据需要进行修改,然后按上述说明回写。

答案 1 :(得分:0)

修改:仅使用add al,ah或任何其他add,这是不可能的。

您可以通过将flags / eflags弹出到某个寄存器中,然后使用or设置所需的标记,推送寄存器并将其弹出到标记中来实现。

对于16位代码(NASM语法):

pushf
pop ax
or ax,0x881
push ax
popf

对于32位代码:

pushfd
pop eax
or eax,0x881
push eax
popfd