如何在 ARM Cortex-M3 上旋转和移位 64 位整数?

问题描述

我有一个 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。