ARM程序集 - 转换字节序

时间:2010-05-02 21:58:11

标签: assembly arm endianness

目前这是我和我的队友坚持的家庭作业项目。我们没有多少介绍大会,这应该是我们的第一个家庭作业。任务是创建一个将0xAABBCCDD转换为0xDDCCBBAA的程序。

我不是在寻找答案,因为这会破坏目的,但我们对这种愚蠢的事情的困难感到非常沮丧。我们认为我们在创建可行的解决方案方面有一个良好的开端,但我们无法提出其余的计划。

首先,我们将每个tupel(aa),(bb),(cc),(dd)掩盖到另一个寄存器中:

LDR R0, LittleEndian    // 0xAABBCCDD
AND R1, R0, #0xFF000000 // 0xAA
AND R2, R0, #0x00FF0000 // 0xBB
AND R3, R0, #0x0000FF00 // 0xCC
AND R4, R0, #0x000000FF // 0xDD

然后我们尝试将它们重新对齐到R0寄存器中,但是如果我们能够提出一个好的解决方案那就太糟糕了......

我们的最大努力来自:

ORR R0, R1, LSL #24 
ORR R0, R2, LSL #8
ORR R0, R3, LSR #8
ORR R0, R4, LSR #24

由于某些奇怪的原因产生0xBBBBCCDD;我们真的不知道。

任何提示都将不胜感激。我们再次寻求帮助,但不是寻求解决方案。

干杯!

5 个答案:

答案 0 :(得分:5)

在ARMv6及更高版本上,您可以使用rev指令,但我认为您无论出于何种原因都不允许这样做。

至于为什么你得到了你所做的结果,我已经完成了你的代码,并评论了所操作的寄存器的实际值:

LDR R0, LittleEndian    // r0 = 0xAABBCCDD
AND R1, R0, #0xFF000000 // r1 = 0xAA000000
AND R2, R0, #0x00FF0000 // r2 = 0x00BB0000
AND R3, R0, #0x0000FF00 // r3 = 0x0000CC00
AND R4, R0, #0x000000FF // r4 = 0x000000DD

ORR R0, R1, LSL #24     // r0 = 0xAABBCCDD | 0x00000000 = 0xAABBCCDD
ORR R0, R2, LSL #8      // r0 = 0xAABBCCDD | 0xBB000000 = 0xBBBBCCDD
ORR R0, R3, LSR #8      // r0 = 0xBBBBCCDD | 0x000000CC = 0xBBBBCCDD
ORR R0, R4, LSR #24     // r0 = 0xBBBBCCDD | 0x00000000 = 0xBBBBCCDD

这里发生的事情是你向后转移方向;而不是左移0xAA000000 24,你想正确将它移动24,得到0x000000AA。此外,您从未将r0的内容归零,您还需要为此方法开展工作。如果您解决了这些问题,您的代码将按预期工作(尽管有更紧凑的方法可以完成相同的任务)。

答案 1 :(得分:3)

到目前为止,您的代码看起来很不错。

你的错误是,你已经颠倒了LSL和LSR的含义。

以R0为例:

AND R1, R0, #0xFF000000 // 0xAA

此操作的结果不会生成0xAA。它生成0xAA000000。

处理R1的第二条指令:

ORR R0, R1, LSL #24 

将数据移出寄存器。前8位没有剩余空间。

如果你将数据移到右边,如下所示:

ORR R0, R1, LSR #24 

数据以最低字节结束。你想要它的地方。这应该会给你足够的帮助来完成你的功课。 : - )

答案 2 :(得分:3)

我认为你需要这样做(ARM有点生疏):

MOV R0, R1, LSR #24 
ORR R0, R2, LSR #8
ORR R0, R3, LSL #8
ORR R0, R4, LSL #24

即第一条指令中的MOV,因为您不希望旧R0中的任何内容影响新值。

我看不出任何方法可以让你更加“暗示”,就像你已经有效地完成了所有的工作一样。

答案 3 :(得分:2)

虽然问题相当陈旧但我想添加我对代码的建议,因为它只需要6个指令而不是8个。它也只需要3个寄存器而不是5个。这应该是之前任何事情的最佳解决方案armv6(具有rev指令)。

// We're starting with r0 = 4321
mov r2, r0, lsr #24             // r2 = 0004
and r1, r0, #16711680           // r1 = 0300
orr r2, r2, r0, lsl #24         // r2 = 1004
orr r2, r2, r1, lsr #8          // r2 = 1034
and r0, r0, #65280              // r0 = 0020
orr r0, r2, r0, lsl #8          // r0 = 1234

答案 4 :(得分:1)

此外,在使用ORR移回位之前,看起来您可能没有清除R0寄存器(将其设置为全零位)。