有没有办法只使用 xorq、andq、addq、iaddq 和 subq 来执行算术右移?
Is there a way to perform arithmetic right shift using only xorq, andq, addq, iaddq, & subq?
我在一个只有这些操作的假设架构中 (Y86)。不存在算术右移。我实际上是在尝试捕获最高位以确定数字是否为负数,如果是,则将其添加到结果寄存器 rax。
编辑:
不好意思,我忘记说明了,我正在尝试避免条件分支,看看它是否提高了效率。我所在的版本不存在cmov
我得到的最远的是:
andq [=10=]x10000000, elem
subq [=10=]x01111111, elem
addq elem, %rax
但是,对于结果 0,这不起作用。
假设您可以使用循环和条件分支:
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 变量必须在寄存器中。结果可以在寄存器中,也可以在内存中。
如果Y86允许MOVQ访问不是QWORD对齐的内存,那么就可以做到。
但我怀疑它是否会比条件分支执行得更好。
诀窍是将数字写入内存,
然后从略'off'的地址重新读取。这有效地将位移动到 8 的倍数。将其与 addq
结合使用可将位向左移动 1 个位置。
请注意,这高度依赖于处理器架构的字节顺序。
以下示例基于小端(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
我在一个只有这些操作的假设架构中 (Y86)。不存在算术右移。我实际上是在尝试捕获最高位以确定数字是否为负数,如果是,则将其添加到结果寄存器 rax。
编辑:
不好意思,我忘记说明了,我正在尝试避免条件分支,看看它是否提高了效率。我所在的版本不存在cmov
我得到的最远的是:
andq [=10=]x10000000, elem
subq [=10=]x01111111, elem
addq elem, %rax
但是,对于结果 0,这不起作用。
假设您可以使用循环和条件分支:
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 变量必须在寄存器中。结果可以在寄存器中,也可以在内存中。
如果Y86允许MOVQ访问不是QWORD对齐的内存,那么就可以做到。 但我怀疑它是否会比条件分支执行得更好。
诀窍是将数字写入内存,
然后从略'off'的地址重新读取。这有效地将位移动到 8 的倍数。将其与 addq
结合使用可将位向左移动 1 个位置。
请注意,这高度依赖于处理器架构的字节顺序。 以下示例基于小端(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