在ARM上切换字节序

5

我听说ARM处理器可以在小端和大端之间切换。处理器为什么需要这个功能?它在安卓手机上使用吗?


1
大多数是营销手段。目前仅有非常少的一些基于ARM指令集且默认为大端模式的产品,而即便是大端模式也与您所想的不同,并且在较新的内核上有处理字节交换的指令。使工具链正常工作等方面都很麻烦。 - old_timer
英特尔收购了DEC,可能是为了打压Alpha处理器,但副作用是StrongARM处理器成为XScale处理器,并默认为大端序(该产品线现在由Marvell公司拥有)。当时它是字不变的(BE-32)(来自arm的新核心是BE-8,字节不变,你只能选择其中之一而不能同时具备两者)。那时候很难让工具链(gnu/gcc)正常工作,尽管BE-8更加复杂,但现在更容易了。 - old_timer
新一代的核心有一种指令,可以切换模式并切换回来,以便您可以拥有一个关键部分。在旧的核心中,这是全局设置,您几乎希望使整个系统成为大端模式。 - old_timer
3个回答

5

根据处理器的不同,可能可以在运行时切换字节序。旧的处理器将以一种字节序启动,并且预计它们将保持在该状态。在后一种情况下,整个设计通常将被设置为大端或小端之一。

支持混合字节序操作的主要原因是支持网络堆栈,在此堆栈中操纵的基础数据集是本地大端序。这对于交换机/路由器和移动基站非常重要,其中处理器正在运行定义良好的软件堆栈,而不是作为通用应用设备运行。

请注意,在不同的ARM架构中,大端行为有几种不同的实现方式,您需要确切地检查任何特定核心的工作方式。


1
没有处理器需要以大端或小端方式运行。原因很简单:你在一种模式下能做的任何事情,在另一种模式下也同样能做到。当然,这通常适用于任何图灵完备计算机,但是通常CPU有指令来反转字内数据。

在ARM中,似乎这个指令被称为rev指令。让我引用Arm的Mali GPU杰出工程师彼得·哈里斯(Peter Harris)的话:

如果你要从内存中加载单个字段,则只需使用小端加载并使用"rev"指令来反转结果——这只是一个额外的指令,速度更快(并且足够小,可以内联,因此避免了函数开销)。

rev指令会颠倒一个字中的字节顺序。虽然像rev这样的指令通常不会颠倒字节内的位顺序,但您可以假定位顺序是固定的(调试字节中的位时通常显示为大端序,例如在查看十六进制表示时)。

请注意,任何超过寄存器容量的数字都应由应用程序正确处理;例如,处理128位的代码不仅需要考虑字节的顺序,还需要考虑2个64位字的顺序。


-4

你可以切换字节序,但在操作系统启动后这样做会导致问题。如果你要这样做,你需要在引导过程的早期阶段进行。当你的应用程序运行时,字节序已经被选择并且不会改变。

为什么要这样做?唯一的原因是,如果你正在编写需要处理大量小端数据的嵌入式软件,或者运行一个假定为小端而没有固定为端无关的程序。这种数据通常来自于以其本地字节顺序(x86为小端)编写输出的x86应用程序。除此之外,没有太多其他的理由去这样做。你会发现ARM几乎完全在大端模式下运行。


3
ARM是小端序,大端序在ARM上是异常情况。 - old_timer
2
这仅适用于ARMv6,可能也适用于大多数ARMv7。在ARMv8中,字节序是动态的(仅应用于数据侧)。 - Sean Houlihane
1
这个讨论关于ARM社区如何设置字节序的问题。如果您需要大端序,通常需要在特权模式下运行代码,并且需要重新编译编译器本身。这基本上意味着除非您的处理器在网络产品中拥有一个特定功能(这可能是它仍然存在的原因),否则不建议这样做。Gabe,也许现在是时候重新审查和调整您的答案了?虽然我非常支持大端序,但是否认现实从来都不是一个好主意。 - Maarten Bodewes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接