ARM平台的数据转换(从x86/x64)
Data conversion for ARM platform (from x86/x64)
我们已经为x86和x64平台开发了win32应用程序。我们希望在ARM平台上使用相同的应用程序。终结性因ARM平台而异,即ARM平台通常使用Big endian格式。因此,我们希望在我们的设备应用程序中处理此问题。
例如//在x86/x64中,int nIntVal = 0x12345678
在ARM中,int nIntVal = 0x78563412
以下数据类型的值将如何存储在ARM中?
- 双重
- char数组,即char chBuffer[256]
- int64
请澄清这一点。
谨致问候,Raphel
Endianess只对寄存器<->有影响内存操作。
在寄存器中没有尾数。如果你放
int nIntVal = 0x12345678
在您的代码中,它对任何endianes机器都具有相同的效果。
所有IEEE格式(float
、double
)在所有体系结构中都是相同的,所以这并不重要。
在两种情况下,您只需要关心endianes:
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
}
顺便说一下,后一段代码是在运行时测试endianes的一种方便方法。
数组等。如果您使用调用的write, fwrite
伪函数来传输它们,除非它们包含整数,否则不会有任何问题:然后查看上面的内容。
int64_t
:看上面。只关心是否必须将它们二进制存储在文件或强制转换指针中。
http://en.wikipedia.org/wiki/Endianness有一个很好的概述。
简而言之:
- Little endian意味着,首先存储最低有效字节(在最低地址)
- 大端序意味着最高有效字节首先存储
数组元素的存储顺序不受影响(当然,数组元素中的字节顺序)
所以
- char数组未更改
- int64字节的顺序与x86相反
关于浮点格式,请考虑http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness。一般来说,它似乎遵循与整数格式相同的字节序规则,但旧的ARM平台也有例外。(我对此没有亲身经历)。
一般来说,我建议先通过对照实验来测试原始类型的转换。
还要考虑的是,编译器可能会在结构中使用不同的填充(这是您尚未讨论的主题)。
希望这能有所帮助。
在98%的情况下,您不需要关心endianness。除非你需要在不同端序的系统之间传输一些数据,或者读/写一些对端序敏感的文件格式,否则你不应该为此烦恼。即使在这种情况下,你也可以编写代码,使其在任何端序下编译时都能正常执行。
来自Rob Pike的"字节顺序谬误"帖子:
假设您的数据流有一个小的endian编码的32位整数。以下是如何提取它(假设为无符号字节):
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
如果它是大端序,以下是提取方法:
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
这两个代码段都适用于任何机器,独立于机器的字节顺序,独立于对齐问题,独立于任何东西它们是完全可移植的,给定无符号字节和32位整数。
arm是little-endian,根据体系结构的不同,它有两个big-endian变体,但最好只运行原生little-eddian,工具和大量代码在little-eendian模式下经过了更全面的测试。
持久性只是系统工程中的一个因素,如果你做系统工程,一切都会成功,没有恐惧,没有担忧。为该设计定义接口和代码。例如,假设一个处理器的字节序自动导致必须进行字节交换,这是一个错误的假设,最终会让你痛苦。你最终将不得不交换偶数次,以撤销导致交换的其他错误假设(当然,理想情况下交换零次,而不是2、4或6次,等等)。如果在编写代码时有任何endian问题,那么应该将其独立于endian编写。
由于一些arm具有BE32(单词不变量)和较新的arm BE8(字节不变量),您将不得不做更多的工作来尝试制作一些通用的东西,同时尝试补偿小英特尔、小arm、BE32 arm和BE8 arm。Xscale倾向于本机运行大端序,但也可以作为小端序运行,以减少麻烦。您可能会认为,因为ARM克隆是big-endian,所以所有克隆都是big-ndian,这是另一个错误的假设。
- 为x86而非x64编译时出错
- 如何在 MSVC C++中迁移 x64 的 x86 代码
- 将内联程序集尾调用函数尾声替换为用于x86/x64 msvc的Intrinsics
- 将程序从x86转换为x64
- 将vector<vector<double>>从x86平台中创建的一个进程发送到x64中构建的另一个进程的最快方法是什么
- 现代C++中STL API的差异(当我在VS2017中将目标从x64切换到x86时)
- 在x64进程中调用x86 winapi函数
- 致命错误LNK1112:在 npm 安装期间,模块计算机类型'X86'与目标计算机类型'x64'冲突
- 在构建服务器上将 dll C++生成到两个平台 (x86+x64)
- C DLL通过C#UWP应用程序中的Win运行时组件适用于ARM,但对于X86/X64不适用于
- VC++ 异常处理在 x86 和 x64 上对于 IBPP / Firebird 客户端有所不同
- LNK2001在X64环境中的编译代码上看到的错误.但是,该代码在X86环境中填充了罚款
- Return value of std::hash ofr (x86/x64)
- 致命错误LNK1112:通过 vcvarsall .bat x86 运行构建'X86'模块计算机类型'x64'与目标计算机类型冲突
- 如何在 x86 和 x64 平台之间使用 boost::序列化
- VS2012 如何将 C# 的 AnyCPU 配置的输出目录设置为各自解决方案配置的 x86 和 x64 文件夹?
- QtGui4.lib(QtGui4.dll):致命错误LNK1112:模块计算机类型"X86"与目标计算机类型"x64"冲突
- ARM平台的数据转换(从x86/x64)
- 使用x86/x64 C API的c# AnyCPU库-打包结构,调用和回调
- 块匹配优化使用x86/x64流SIMD扩展