我有一个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
Run Code Online (Sandbox Code Playgroud)
在c:
t=x^(x>>8);
t=t&0xFF00;
t=t|(t<<8);
x^=t;
Run Code Online (Sandbox Code Playgroud)
在每一行之后,计算的结果是:从:AABBCCDD开始
eor XXXXEEXX
and 0000EE00
orr 00EEEE00
eor AACCBBDD
Run Code Online (Sandbox Code Playgroud)
这适用于任何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
Run Code Online (Sandbox Code Playgroud)
这逐行转换为以下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;
}
Run Code Online (Sandbox Code Playgroud)
你会看到 - 这么简单的任务有很多行.甚至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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
16185 次 |
最近记录: |