在没有跳转的程序集中实现eq,lt gt

时间:2010-01-21 21:51:00

标签: assembly bit-manipulation

是否可以仅使用AND,OR和NOT运算符编写逻辑来比较2个操作数并返回true / false(-1,0)而不使用跳转? 如果是的话,请你给我一些提示,因为它对我来说是不可能的。 我正在尝试使用书籍"The Elements of Computing Systems"的汇编语言实现eq,lt和gt。

7 个答案:

答案 0 :(得分:5)

如果仅使用按位逻辑运算符,并且在进位丢失的位置加/减,则无法从比较运算中获得-1或0(或者1或0的结果)的结果:< / p>

  • 对于按位运算符,结果的位 n 仅取决于两个操作数的位 n

  • 另外,请考虑二进制加法的工作原理:结果的 n 位可能会受到位 n 的影响,位<位>的位<每个操作数的em> n (通过进位);但不能受操作数中 n 位左侧任何位的影响。 (您可以认为这是观察的一般化,即添加两个偶数不能给出奇怪的结果。)

  • 由于单个加法或按位运算不能将操作数的 n 位左侧的任何信息传播到结果的位 n 中,因此也不能添加或按位运算的组成;和减法(假设这里的2的补码)可以被认为是这样的组合:x-y = x +(NOT y)+1。

因此,对于2 == 2,你不能得到0的结果,但是对于2 == 4,得到-1(或1)的结果,例如:在每种情况下,所需结果的第0位是不同的,但结果是只能依赖于两个操作数的第0位,在每种情况下都是相同的。

如果您的真假值仅在 top (即最左侧)位有所不同,则可以完成。

例如,使用8位值:使用0x80表示true,0表示false;然后x == y可以(NOT((x - y) OR (y - x))) AND 0x80实现。

如果可用操作扩展到包括右移,或者如果ADD操作可以产生一个可以重新添加到结果底部的进位,则可以解决最初声明的问题。

答案 1 :(得分:2)

XOR a, b
如果a和b相等,

将导致0,否则将导致非零值。

SUB a, b
AND a, SIGN_BIT

(其中SIGN_BIT是除去......符号位之外的所有内容的掩码)

如果a大于b,则

将导致零;如果a小于或等于b,则<0>将导致非零(假设2是完全的)。

答案 2 :(得分:1)

以防万一这是一个纯粹的理论问题:由于你在一组有限的操作数上运算,所有可能的函数只能用OR,AND和NOT表示。

有关详细说明,请参阅Disjunctive normal form

出于实际目的,Anons的答案更有用:-) ......

编辑:即使我的理论答案可能也不是这样:将析取范式应用于此问题需要移位操作,因为输出字的每个位都取决于输入位的所有位。我还没有弄清楚如何使用AND,OR,NOT和算法来实现移位(我不确定这是否可能......)

我离开这个帖子虽然是过早回答的反面例子......

答案 3 :(得分:1)

等于B可以用xor表示:

(A AND (NOT B)) OR ( A AND (NOT B))

如果A == B,则输出0,如果不是

,则输出!= 0

对于A小于B,您可以使用     (A - B和SIGN_MASK)

,其中SIGN_MASK屏蔽了除符号位之外的所有内容,它将为您提供MAX_NEGATIVE_INTEGER的真值和0的假值。

大于可以从少于

构造

答案 4 :(得分:0)

你正在谈论的汇编语言中的所有算术运算都有可能根据操作的结果(= 0?和&gt; 0?)进行条件跳转,这可以用来获得所需的布尔值结果

答案 5 :(得分:0)

我们正在阅读同一本书并且遇到了这个问题。

我们能找到的最佳解决方案是生成唯一标签,然后使用JEQ命令跳转到预期的标签,然后在完成后再跳转到标签。

伪代码:

if they're equal, jump to EQUAL

// not equal section
push constant false
jump to DONE

// equal section
(EQUAL)
push constant true

// done section
(DONE)

Here是我们如何具体实现它(在Ruby中)。

答案 6 :(得分:-1)

x86从历史上的某个点开始的CPU已经进行了“条件移动”操作。