有没有一种方法可以仅使用xorq,andq,addq,iaddq和subq执行算术右移?

时间:2018-11-19 20:35:47

标签: assembly y86

我处于一个仅具有那些操作的假设体系结构(Y86)。不存在算术右移。我本质上是试图捕获最高位以确定该数字是否为负,如果是,则将其添加到结果寄存器rax中。

编辑:

对不起,我忘记指定了,我试图避免条件分支来查看它是否提高了效率。我使用的版本中没有cmov。

我得到的最远的是:

andq $0x10000000, elem
subq $0x01111111, elem
addq elem, %rax

但是,结果为0无效。

2 个答案:

答案 0 :(得分:1)

假设您可以使用循环和条件分支:

    mov result, 0
    mov lead, 2
    mov follow, 1
1:
    mov tmp, n
    and tmp, lead
    jz 2f
    add result, follow
2:
    add follow, follow
    add lead, lead
    jnz 1b

tmp,lead和follow变量必须位于寄存器中。结果可以在寄存器或内存中。

答案 1 :(得分:1)

如果Y86允许MOVQ访问未QWORD对齐的内存,则可以完成此操作。 但是我怀疑它是否会比条件分支更好。

诀窍是将数字写入内存, 然后从稍微“关闭”的地址再次读取。这样可以有效地将位移位8的倍数。将其与addq结合使用可将位1的位置向左移动。

请注意,这高度依赖于处理器体系结构的字节顺序。 以下示例基于little endian(Intel样式)。 在大端上,必须调整偏移量。

(如果您喜欢AT&T语法,请反转操作数并除去括号。)

movq rbx,number         ; sign bit is bit 63 of rbx
movq [address],rbx      ; sign bit is most significant bit of the byte at [address+7]
movq rbx,[address+4]    ; sign bit is bit 31 of rbx
addq rbx,rbx            ; sign bit is bit 32 of rbx
movq [address],bx       ; sign bit is least significant bit of the byte at [address+4]
movq rbx,[address+4]    ; sign bit is bit 0 of rbx
andq rbx,1              ; rbx = 0 for positive number, rbx = 1 for negative number
addq ax,bx