我正在尝试将寄存器设置为12000.由于MOV在I图12000/2 ^ 8 = 375中不能设置大于255的值。但是375仍然太大而且不能被2整除。唯一剩下的就是将12000存储在内存中吗?效率低得多吗?
出于好奇,为什么它是255而不是256,因为它是未签名的?
答案 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。它往往更快。