将移位的立即值加载到寄存器中的单条指令?

Single instruction to load shifted immediate value into a register?

我似乎无法找到一种方法,通过一条指令将一个立即值放入寄存器中非最低位的位置。

例如,假设您希望寄存器为 r1 = 0x00110000。然后,一种多指令的方法是。

mov r1, #0x11
lsl r1, #16

我正在使用多种设备,其中一些设备允许高达 32 位的立即值,但大多数设备不允许,所以我只能使用基本的 ARM 指令。

让你的 assembler 为你编码移位/旋转,给它 0x00110000 值。

大多数 assemblers(包括所有 ARM assemblers?)支持 assemble-time 常量表达式,因此您可以编写

mov r1, #0x11 << 16

这将assemble在ARM模式下变为11 18 a0 e3。但在 Thumb 模式下,它需要 ARMv6 Thumb2。有关 MOV 的可用形式,请参阅 http://www.keil.com/support/man/docs/armasm/armasm_dom1361289878994.htm

可能更好的选择是 LDR 伪指令,它允许 assembler 在相对于 PC 的加载(来自文字池)或带有某种编码的 mov-immediate 之间进行选择。 http://www.keil.com/support/man/docs/armasm/armasm_dom1359731145835.htm(这是 keil 的 assembler 文档,但 GAS 和 clang 也支持相同的语法。)

ldr r1, =0x11 << 16

I'm working with several devices

考虑为每台设备重建,这样您就可以为每台设备优化代码。特别是如果您使用 ldr reg, =value - 它可以在可用时使用 mov.w reg, #imm16

and some of them allow immediate values up to 32 bits

如果您谈论的是 ARMv6T2 movt / movw,那是两条 32 位指令,每条指令提供 16 位的一半。

没有 ARM 能够用一条指令编码任意 32 位常量;这将不会为 32 位指令中的操作码留下任何位。