ARM平台的数据转换(来自x86 / x64)

时间:2013-08-07 09:50:01

标签: c++ c arm

我们为x86和x64平台开发了win32应用程序。我们想在ARM平台上使用相同的应用程序。对于ARM平台,字节顺序会有所不同,即ARM平台通常使用Big endian格式。因此,我们希望在我们的设备应用程序中处理此问题。

例如//在x86 / x64中,int nIntVal = 0x12345678
在ARM中,int nIntVal = 0x78563412

如何为ARM中的以下数据类型存储值?

  1. char数组,即char chBuffer [256]
  2. 的int64
  3. 请澄清一下。

    此致 Raphel

4 个答案:

答案 0 :(得分:5)

Endianess仅适用于注册表< - >记忆操作。

在注册表中没有任何结尾。如果你把

int nIntVal = 0x12345678

在您的代码中,它将对任何endianess机器产生相同的效果。

所有IEEE格式(floatdouble)在所有体系结构中都是相同的,所以这并不重要。

在两种情况下你只需要关心结束:

a)您将整数写入必须在两种体系结构之间转换的文件。 解决方案:使用hton*, ntoh*系列转换器,使用非二进制文件格式(例如XML)或标准化文件格式(例如SQLite)。

b)你转换整数指针。

int a = 0x1875824715;
char b = a;
char c = *(char *)&a;
if (b == c) {
    // You are working on Little endian
}

顺便说一句,后一种代码是一种在运行时测试你的endianess的便捷方法。

数组等等如果你使用write, fwrite调用来传递它们,你将没有任何问题,除非它们包含整数:然后看看上面。

int64_t:看看上面。只关心你是否必须将二进制文件存储在文件或转换指针中。

答案 1 :(得分:0)

(Sergey L.,上面说,但是你大部分时间都不需要关心字节顺序。他是对的,至少有一个例外:我假设你想要将二进制数据从一个平台转换到另一个平台......)

http://en.wikipedia.org/wiki/Endianness有一个很好的概述。

简而言之:

  • 小端表示,最低有效字节首先存储(在最低地址处)
  • Big endian表示首先存储最重要的字节

存储数组元素的顺序不受影响(当然是数组元素中的字节顺序)

所以

  • char数组未更改
  • int64 - 与x86相比,字节顺序相反

关于浮点格式,请考虑http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness。通常,它似乎遵循与整数格式相同的字节序规则,但旧的ARM平台也有例外。 (我没有第一手经验)。

一般来说,我建议先用受控实验测试原始类型的转换。

还要考虑,编译器可能在结构中使用不同的填充(这个主题尚未解决)。

希望这有帮助。

答案 2 :(得分:0)

在98%的情况下,您不需要关心字节序。除非你需要在不同endiannness的系统之间传输一些数据,或者读/写一些endian敏感文件格式,否则你不应该为此烦恼。即使在这些情况下,您也可以编写代码,以便在任何字节序下编译时正常运行。

来自Rob Pike的"The byte order fallacy"帖子:

  

假设您的数据流具有小端编码的32位整数。   以下是如何提取它(假设无符号字节):

i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
     

如果它是big-endian,这是如何提取它:

i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
     

这两个片段都适用于任何机器,独立的机器   字节顺序,独立于对齐问题,独立于   任何东西。它们是完全可移植的,给定无符号字节和32位   整数。

答案 3 :(得分:0)

arm是小端,它有两个大端变体,具体取决于体系结构,但最好只运行本机小端,其中的工具和代码量在小端模式下进行了更全面的测试。

如果您进行系统工程,那么Endianness只是系统工程中的一个因素,它可以解决所有问题,无需担心,无后顾之忧。为该设计定义接口和代码。假设例如一个处理器字节序自动导致必须使用byteswap是一个不好的假设并且最终会咬你。您最终必须交换偶数次以撤消导致交换的其他错误假设(理想情况下当然交换零次而不是2或4或6次等)。如果您在编写代码时有任何endian问题,则应将其编写为endian independent。

由于某些ARM具有BE32(字不变)和较新的臂BE8(字节不变),您将不得不做更多的工作来尝试制作通用的东西,同时试图补偿小的英特尔,小臂,BE32臂和BE8手臂。 Xscale倾向于本地运行大端,但可以作为小端运行以减少头痛。您可能认为因为ARM克隆是大端,所以都是大端,另一个不好的假设。