Assembly 如何在ARM组装中交换相邻位

Assembly 如何在ARM组装中交换相邻位,assembly,arm,Assembly,Arm,如何交换ARMV7中的相邻位?例如: 0x87654321 -> 0x4B9A8312 10000111011001010100001100100001 -> 01001011100110101000001100010010 右移1,将奇数位归零。向左移位,将偶数位归零。将奇数位归零,向左移位。最后,还是一起 编辑:要将奇数位归零,可以使用AND命令和掩码(即常量值),其中所有奇数位都有零。对于32位ARM寄存器,这是0x5555。对于每个nybble,位0和2是1(位值1和4加

如何交换ARMV7中的相邻位?例如:

0x87654321 -> 0x4B9A8312

10000111011001010100001100100001 ->
01001011100110101000001100010010

右移1,将奇数位归零。向左移位,将偶数位归零。将奇数位归零,向左移位。最后,还是一起

编辑:要将奇数位归零,可以使用AND命令和掩码(即常量值),其中所有奇数位都有零。对于32位ARM寄存器,这是
0x5555
。对于每个nybble,位0和2是1(位值1和4加上5),位1和3以及0,依此类推

不管怎样,代码来了。假设源值在
r0
中,结果也在那里。使用Peter的想法,我们将奇数位归零,然后移位,而不是移位,然后再归零。利用特定于ARM的功能,第二个操作数可以作为较大操作的一部分免费移位(或旋转)

ldr r12, =0x55555555    //Load the mask for only even bits 

and r1, r12, r0, lsr #1 //r1 = (r0 >> 1) & mask, odd bits shifted right
and r2, r0, r12         //r2 = r0 & mask, even bits only
orr r0, r1, r2, lsl #1  //r0 = r1 | (r2 << 1), (odd bits shifted right) OR (even bits shifted left)
对于Thumb模式下的超标量CPU,这可能具有更差的延迟。通过使用低位寄存器(r0..7),原始想法也可以实现同样的保存<代码>和r0、r3是一条2字节指令,不同于

// Thumb 2 optimized version of the first version, overwrites r0 earlier
mov   r3, #0x55555555
and   r1, r3, r0, lsr #1         //r1 = (r0 >> 1) & mask, odd bits shifted right
ands  r0, r3                     //r0 &= mask, even bits only.  2 bytes
orr   r0, r1, r0, lsl #1         //r0 = r1 | (r0 << 1), (odd bits shifted right) OR (even bits shifted left)
//Thumb 2第一个版本的优化版本,覆盖之前的r0
mov r3#0x5555
r1,r3,r0,lsr#1//r1=(r0>>1)和掩码,奇数位右移
ands r0,r3//r0&=掩码,仅限偶数位。2字节

orr r0,r1,r0,lsl#1//r0=r1 |(r0右移1,将奇数位置零。左移,将偶数位置零。将奇数位置零,将左移。最后,或一起

编辑:要将奇数位归零,使用AND命令和掩码(即一个常量值),其中所有奇数位都有零。对于32位ARM寄存器,这是
0x555555
。对于每个Nyble,位0和2是一(位值1和4加上5),位1和3以及零,依此类推

无论如何,代码就在这里。假设源值在
r0
中,结果也在那里。使用Peter的想法,我们将奇数位归零,然后移位,而不是移位,然后归零。利用ARM特有的功能,第二个操作数可以作为更大操作的一部分免费移位(或旋转)

ldr r12, =0x55555555    //Load the mask for only even bits 

and r1, r12, r0, lsr #1 //r1 = (r0 >> 1) & mask, odd bits shifted right
and r2, r0, r12         //r2 = r0 & mask, even bits only
orr r0, r1, r2, lsl #1  //r0 = r1 | (r2 << 1), (odd bits shifted right) OR (even bits shifted left)
对于Thumb模式下的超标量CPU,这可能会有更差的延迟。通过使用低寄存器(r0..7),原始想法也可以进行同样的保存。
和r0、r3
是一条2字节指令,与
不同

// Thumb 2 optimized version of the first version, overwrites r0 earlier
mov   r3, #0x55555555
and   r1, r3, r0, lsr #1         //r1 = (r0 >> 1) & mask, odd bits shifted right
ands  r0, r3                     //r0 &= mask, even bits only.  2 bytes
orr   r0, r1, r0, lsl #1         //r0 = r1 | (r0 << 1), (odd bits shifted right) OR (even bits shifted left)
//Thumb 2第一个版本的优化版本,覆盖之前的r0
mov r3#0x5555
r1,r3,r0,lsr#1//r1=(r0>>1)和掩码,奇数位右移
ands r0,r3//r0&=掩码,仅偶数位。2字节

orr r0,r1,r0,lsl#1//r0=r1 |(r0明显的可移植方式是evenbits=0x5555…;
((x>>1)和evenbits)((x和evenbits)您是在优化ARM模式还是Thumb模式?Thumb可以立即执行位模式,因此它实际上非常适合于
0x555555
之类的常量。显而易见的可移植方式是evenbits=0x5555…;
((x>>1)和evenbits)|((x&evenbits)你是在优化ARM模式还是Thumb模式?Thumb可以立即执行位模式,因此它实际上非常适合于
0x555555
之类的常量。我对ARM编程不太熟悉。我如何将奇偶位归零?你能告诉我在ARM代码中需要什么吗?你只需要一个掩码常量;在移位之前使用它,在移位之后使用它如果您不打算专门针对ARM对其进行优化,并使asm比编译器更小和/或更快,那么已经有了一个C副本(),IMO,没有理由回答这个问题,也许只是评论一下。明白了!谢谢!我对ARM编程不太熟悉。我如何将奇偶位归零?你能告诉我我在ARM代码中寻找什么吗?你只需要一个掩码常量;在用一个掩码常量移位之前使用它,在用另一个掩码常量移位之后使用它。已经有一个C重复(),如果您不打算专门针对ARM进行优化,也不打算制作比编译器更小和/或更快的asm(),IMO没有理由回答这个问题,也许可以发表评论。明白了!谢谢!