我有一个32位(十六进制)字0xaabbccdd,必须交换2.和3.字节.最后它应该看起来像0xaaccbbdd
如何"掩盖"第2和第3个字节,首先将它们加载到寄存器r1和r2并交换它们..我也知道我必须使用lsl和lsr命令,但不知道如何启动.
抱歉,我的英语不好.任何人都可以帮助我!
问候,塞巴斯蒂安
回到过去,我们过去常常依赖EOR来获取这种诡计.
你可以在4个周期内完成.
首先,我们需要这样的事实:A ^(A ^ B)= B.
我们从0xAABBCCDD开始,我们想要0xAACCBBDD.为此,我们需要0x00EEEE00 ^ 0xAABBCCDD,其中EE = BB ^ CC.
现在,我们需要几个周期来构建00EEEE00:
eor r1,r0,r0,lsr #8 and r1,r1,#0xFF00 orr r1,r1,r1,lsl #8 eor r0,r0,r1
在c:
t=x^(x>>8); t=t&0xFF00; t=t|(t<<8); x^=t;
在每一行之后,计算的结果是:从:AABBCCDD开始
eor XXXXEEXX and 0000EE00 orr 00EEEE00 eor AACCBBDD
这适用于任何32位ARM内核.
这不是ARM组装中的简单任务,因为您不能轻易使用32位常量.你必须分解掩盖字节的所有操作,每个操作使用8位常量(也可以旋转这些常量).
使用AND指令屏蔽byte2和3并稍后进行移位.在ARM汇编程序中,您可以免费获得大多数指令一个移位,因此移位到位并与其他位合并通常最终成为单个指令.
这是一些未经测试的代码,它执行中间字节交换(ARMv4,而不是拇指指令集):
.text swap_v4: AND R2, R0, #0x00ff0000 @ R2=0x00BB0000 get byte 2 AND R3, R0, #0x0000ff00 @ R3=0x0000CC00 get byte 1 BIC R0, R0, #0x00ff0000 @ R0=0xAA00CCDD clear byte 2 BIC R0, R0, #0x0000ff00 @ R0=0xAA0000DD clear byte 1 ORR R0, R2, LSR #8 @ R0=0xAA00BBDD merge and shift byte 2 ORR R0, R3, LSL #8 @ R0=0xAACCBBDD merge and shift byte 1 B LR
这逐行转换为以下c代码:
int swap (int R0) { int R2,R3; R2 = R0 & 0x00ff0000; R3 = R0 & 0x0000ff00; R0 = R0 & 0xff00ffff; R0 = R0 & 0xffff00ff; R0 |= (R2>>8); R0 |= (R3<<8); return R0; }
你会看到 - 这么简单的任务有很多行.甚至ARMv6架构也没有帮助.
编辑:ARMv6版本(也未经测试,但两个指令更短)
swap_v6: @ bits in R0: aabbccdd ROR R0, R0, #8 @ r0 = ddaabbcc REV R1, R0 @ r1 = ccbbaadd PKHTB R0, R0, R1 @ r0 = ddaaccbb ROR R0, R0, #24 @ r0 = aaccbbdd BX LR