3

在 ARM 汇编中,立即数由 8 位旋转值编码,这意味着我们只能编码

(0-256)^2n.

现在我的问题是我想清除 r0 的高 16 位并将其替换为存储的半字 r1。但是由于立即数的范围有限,我必须做:-

bic r0, r0, #0xff000000
bic r0, r0, #0x00ff0000
add r0, r0, r1, LSL #16

是否可以用一条指令替换 2 条 bic 指令?0xffff0000 是不可编码的。也许我应该使用另一个逻辑操作来清除高 16 位?

谢谢

编辑:对不起,我忘了说 r1 的前 16 位是空的,我使用的是 ARM7TDMI

4

7 回答 7

5

如果您有足够新的 ARM 内核,那么问题很简单:

movt    r0, #0
orr     r0, r0, r1,lsl#16

http://www.keil.com/support/man/docs/armasm/armasm_cjagdjbf.htm

但是,如果您确实有 ARMv6+,您实际上可以一口气完成整个引用的示例:

pkhbt   r0, r0, r1,lsl#16

http://www.keil.com/support/man/docs/armasm/armasm_cihjedjg.htm

于 2008-11-17T12:42:35.290 回答
4

怎么样:

orr r0,r1,r0,lsl #16
mov r0,r0,ror #16

(这假设 r1 的上半字是空的,就像您的参考代码所做的那样。)根据具体情况,您可以通过将最后的 mov 与稍后的代码合并来省略它。

于 2008-11-16T22:35:28.433 回答
2

“用存储的半字 r1 替换它” - 这是否意味着您可以假设 r1 的前 16 位为零?如果是这样的话,

add r0, r1, r0 lsl #16
mov r0, r0 ror #16

将 mov 视为一个占位符,因为您可以希望将 ror 移动到下一个将 r0 作为输入的任何位置,并在同一循环中实际执行有用的工作。

于 2008-11-16T21:57:05.717 回答
1

在 ARMv6(例如 MPCore)上,你可以说

    uxth    r1, r1
    orr     r0, r1, r0, asl #16
于 2008-11-16T21:43:41.593 回答
0

如果你能清除整个事情,你可以xor用它自己。

如果您需要保留下半部分,您是否可以将寄存器左移 8 位并返回?不过,这可能是相同数量的指令。

于 2008-11-16T18:56:34.757 回答
0

对于 C 代码

 (a<<16)|((short)b)

gcc 生成

    mov     r1, r1, asl #16
    mov     r1, r1, asr #16
    orr     r0, r1, r0, asl #16

它不使用任何立即数——不过,它仍然是两条指令。

于 2008-11-16T19:42:46.003 回答
0

您可以使用 BFC 指令。位字段清除。该指令从 m 位中清除 n 位

于 2014-04-29T14:37:01.177 回答