在ARM程序集中,immediates由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答案 0 :(得分: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
答案 1 :(得分:4)
怎么样:
orr r0,r1,r0,lsl #16
mov r0,r0,ror #16
(这假设r1的上半字是空的,就像你的参考代码一样。) 根据具体情况,您可以通过将其与稍后的代码合并来省略最终的mov。
答案 2 :(得分:2)
“用半字存储的r1替换它” - 这是否意味着你可以假设r1的前16位为零?如果是的话,
add r0, r1, r0 lsl #16
mov r0, r0 ror #16
将mov视为占位符,因为您可以将ror移动到接下来将r0作为输入的任何内容,并且实际上在同一周期中执行有用的工作。
答案 3 :(得分:1)
在ARMv6(例如MPCore)上,您可以说
uxth r1, r1
orr r0, r1, r0, asl #16
答案 4 :(得分:0)
如果你能清除整件事,你可以自己xor
。
如果您需要保留下半部分,您是否可以将寄存器左移8位并返回?但是,这可能是相同数量的指令。
答案 5 :(得分:0)
对于C代码
(a<<16)|((short)b)
gcc生成
mov r1, r1, asl #16
mov r1, r1, asr #16
orr r0, r1, r0, asl #16
不使用任何立即 - 但它仍然是两个指令。
答案 6 :(得分:0)
您可以使用BFC指令。位字段清除。该指令从m位清除n位