我该怎么做 将四个字节的数组合并为一个32位。第一项应该进入 最重要的蚕食结果。将结果存储在32位变量结果中。
输入: [LIST] = 0xC,0x2,0x6,0x9 (每个项目都是一个字节,使用DCB来定义字节类型的变量)
输出: [结果] = 0x0C020609
编辑答案:
ADD R1, R0
MOV R1, R1, LSL #8
ADD R0, R0, #8
ADD R1, R0
MOV R1, R1, LSL #8
ADD R0, R0, #8
ADD R1, R0
MOV R1, R1, LSL #8
ADD R0, R0, #8
ADD R1, R0
答案 0 :(得分:1)
您所描述的与将4个连续字节视为以big-endian字节顺序存储的32位整数相同。
根据gcc(在Godbolt compiler explorer上),从big-endian到ARM-native endby的字节交换的最佳方法是使用ARM为此目的明确提供的指令:
rev r0, r0
#include <stdint.h>
#include <endian.h>
#include <string.h>
// type-punning with unions is an alternative to memcpy from a char array to an int
union be_bytes {
uint32_t be_word;
char bytes[4];
};
uint32_t be_bytes_to_native( char *array ) {
union be_bytes tmp;
memcpy(tmp.bytes, array, 4); // memcpy since we take a char* arg instead of a union be_bytes * arg.
// I *think* (union be_bytes*)array would be safe, but I'm not 100% sure.
// GNU C and many other compilers guarantee that writing one union member and reading another is safe. ISO C doesn't, so this technically isn't portable.
return be32toh(tmp.be_word); // from endian.h, uses compiler builtins, inline asm, or some C shift and mask instructions.
}
编译到
be_bytes_to_native:
ldr r0, [r0] @ unaligned
rev r0, r0
bx lr
如果没有REV指令,@ dwelch对Endianness conversion in ARM的回答建议在ARM中进行字节交换32位值的4指令序列:
eor r3,r1,r1, ror #16
bic r3,r3,#0x00FF0000
mov r0,r1,ror #8
eor r0,r0,r3, lsr #8
请注意这是如何将桶形移位器与MOV以外的指令结合使用的。我仍然不确定你的代码中应该是ADD R0, R0, #8
(r0 + = 8)。
答案 1 :(得分:0)
*result* = 0 for each *byte* from *list*: shift *result* 4 bits left ; move previous values to make room for next one AND *byte* with mask to keep only lower 4 bits (0x0F)room OR *masked byte* to *result* ("add" would work too, as all is masked properly) done.
编辑后关于您的代码:
我很确定它会做出与你想要的不同的事情,但我不确定这是哪种CPU /方言,让我想起ARM。
如果LDR R0,=LIST
一次性获取所有4个字节,那就很聪明。
但是你用MSB屏蔽R0(所以你知道你的平台的字节顺序,这个是第一个?)并将其存储在R1中(从某种意义上说,将第一个字节提取到R1进入MSB位置)。
然后你将4添加到R0(对我没有任何意义,破坏最后一个字节值)。然后你将第二个字节提取到R1(覆盖R1的前一个值)等等......
最后你存储到R1和RESULT第四个字节值+ 12(结果= 0x00000015)。
顺便说一下,您应该编译代码,并在某些调试器中进行调试,看看您做了什么,您将以更快的速度学习。只是在纸上猜测,当你拥有真正的硬件几乎是免费的?我不得不在纸上编码,因为我每周只能访问一次实际硬件3小时,所以我几乎没有时间将代码重新键入计算机,运行它,看着它崩溃(我当时都不知道调试器),我还有一周的文书工作来弄清楚发生了什么,修复它,再试一次......但是今天你可以简单地将它输入机器,编译,并逐步指令进入它。可以更容易。