在Arm中表达大量数字

时间:2011-11-07 02:07:13

标签: assembly arm

我正在尝试将寄存器设置为12000.由于MOV在I图12000/2 ^ 8 = 375中不能设置大于255的值。但是375仍然太大而且不能被2整除。唯一剩下的就是将12000存储在内存中吗?效率低得多吗?

出于好奇,为什么它是255而不是256,因为它是未签名的?

4 个答案:

答案 0 :(得分:5)

您定位的是什么ARM拱门?在ARMv7上,有一个非常好的解决方案 - movw指令,它立即采用16位:

movw r0, #12000

在ARMv7之前,您需要使用两个步骤:

mov  r0,     #0x00002e00
orr  r0, r0, #0x000000e0

请注意,可表达的不仅仅是八位宽;它们被任意偶数偏移旋转8位。或者,您只需从内存中加载值,而不是使用立即数。

答案 1 :(得分:5)

传统上arm允许8或9位和一个移位,所以12000 = 0x2EE0,正如斯蒂芬指出你可以这样做:

mov r0, #0x2E00
orr r0, #0x00E0

另一种方式,快捷方式是:

ldr r0,=0x2EE0

这意味着汇编程序会找到一个放置该值然后执行pc相对加载的位置,或者您可以自己执行此操作:

ldr r0,mynumber
...
mynumber: .word 12000

指令集的较新扩展允许立即有更多位。我通常使用

ldr r0,=0x2EE0

解决方案,并确保我有无条件分支,基本上是汇编程序放置变量的池。编译器通常做同样的事情,如果他们不能在单个指令中使用,那么他们倾向于使用负载pc而不是多个直接指令。

答案 2 :(得分:2)

32位的12位被分配给立即值。

制作模式的8位,剩余的4位模式的16个位置:

0x000000ff
0x000003fc
0x00000ff0
0x00003fc0
0x0000ff00
0x0003fc00
0x000ff000
0x003fc000
0x00ff0000
0x03fc0000
0x0ff00000
0x3fc00000
0xff000000
0xfc000003
0xf000000f
0xc000003f

将8位模式放在8位集上。

请注意,上面的顺序与4位的实际值不匹配。你真的不需要知道那种东西,除非你打算在运行时写一些自我改变的代码,无论出于何种原因。

如果要将任意32位值加载到r0中,请使用伪指令ldr和'='

ldr r0,= 0x12345678

然后,汇编程序将根据编译时的体系结构将其转换为最有效的程序。

答案 3 :(得分:1)

它是255,因为二进制的8位数从00000000-11111111开始。 11111111是十进制的255。您可以使用XOR在寄存器之间交换值而不是MOV。它往往更快。