问题描述
我有一个 64 位的数量,其中最高有效的 32 位在 R2 中,最低有效的 32 位在 R3。
如何将 64 位逻辑和算术右移 4 位?
另外,我如何将这些 64 位右旋转 2 位。
如何在 32 位 ARM 上用最少的指令数做到这一点?
解决方法
unsigned long long fun ( unsigned long long x,unsigned int y)
{
return(x<<y);
}
Disassembly of section .text:
00000000 <fun>:
0: f1a2 0c20 sub.w r12,r2,#32
4: fa00 fc0c lsl.w r12,r0,r12
8: f1c2 0320 rsb r3,#32
c: 4091 lsls r1,r2
e: fa20 f303 lsr.w r3,r3
12: ea41 010c orr.w r1,r1,r12
16: 4090 lsls r0,r2
18: 4319 orrs r1,r3
1a: 4770 bx lr
如果我有两个 4 位寄存器保存一个 8 位值 abcd efgh 并且我想将其左移 3 位,那么这两个部分都需要左移 3 位
abcd -> d000
efgh -> h000
But also the lower has to shift right one bit (4-3 = 1)
efgh -> 0efg
Then add/or d000 and 0efg giving the result
defg h000
指令集或编程语言在这里通常无关紧要,您可以使用多种语言和指令集来完成上述操作。
有些指令集只有一个位移位,但也有许多指令集通过进位循环一个位,所以一个位移将用
clear carry
rotate lower through carry one bit
rotate upper through carry one bit
您可以在循环中重复此操作,或者根据需要展开尽可能多的位。
当然,您可以移动的位数不受限制,使用 32 位寄存器和足够的内存,您可以将 123456 字节数移动 n 位。
右移,左移,旋转都是一样的概念,实现就行了。
另一个例子。
unsigned long long fun ( unsigned long long x)
{
return(x<<3);
}
0: 4603 mov r3,r0
2: 00c9 lsls r1,#3
4: 00c0 lsls r0,#3
6: ea41 7153 orr.w r1,r3,lsr #29
a: 4770 bx lr
32 - 3 = 29。