0

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

是否可以使用单个指令添加两个 8 位数字以设置要设置的进位、溢出和符号标志add

我认为不可能得到这个标志组合。为了使 S 标志与 O 标志一起设置,两个数字的最高有效位必须为 0,结果的最高有效位必须为 1。这让我们无法通过添加最高有效位生成进位。

这是我第一次在这个网站上提问,如果我做错了什么,我深表歉意。提前致谢。

编辑:我只能使用以下三个指令:

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

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

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

(编者注:最后一句话没有意义。这是 Parity 或 Zero Flag 的拼写错误,还是他的意思是 CF 不能在之前设置addb?它是add,不是adc,所以它不依赖于以前的标志状态. 将此保留为编辑,而不是在评论中要求澄清,因为这是一个可能无法得到答复的老问题。如果/当您修复关于“不能设置进位标志”的句子时,请编辑此注释,Shan。)

4

2 回答 2

4

用 CF=SF=OF=1是不可能add ah, al的。正式的证明会有些冗长,但是一个简单的详尽测试证实了在add指令之后这种标志状态组合是不可能的。


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

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

于 2013-03-11T02:39:33.617 回答
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
于 2013-03-11T02:37:41.903 回答