【问题标题】:What makes a system little-endian or big-endian?什么使系统小端或大端?
【发布时间】:2012-03-03 11:38:45
【问题描述】:

我对系统/cpu/程序的字节顺序感到困惑。
所以我必须问一些问题让我的思路清晰。

问题 1

如果我只在我的 C++ 程序中使用 char 类型:

void main()
{
    char c = 'A';
    char* s = "XYZ";    
}

然后将此程序编译成一个名为a.out的可执行二进制文件。
a.out 可以在 little-endian 和 big-endian 系统上运行吗?

问题 2

如果我的 Windows XP 系统是 little-endian,我可以在 VMWare/VirtualBox 中安装 big-endian Linux 系统吗? 什么使系统小端或大端?

问题 3

如果我想写一个字节顺序无关的 C++ 程序,我需要考虑什么?

【问题讨论】:

  • 你不应该永远期望一个编译的可执行文件可以在任何地方运行它不是为它编译的。
  • 除非它实际上没有被编译。 IE。托管语言。尽管这也有一些注意事项。
  • @mydogisbox:当然我在这里指的是 C++。我认为这同样适用于托管 C++(虽然不确定)。
  • 据我了解,托管 C++ 在虚拟机 (CLR) 上运行,因此它实际上可能更独立于平台。

标签: c++ endianness


【解决方案1】:

a.out 可以在 little-endian 和 big-endian 系统上运行吗?

不,因为几乎任何两个具有不同字节序的 CPU 都不会运行相同的指令集。 C++ 不是 Java;你不会编译成可以编译或解释的东西。您编译为特定 CPU 的程序集。字节序是 CPU 的一部分。

但这不属于字节序问题。您可以为不同的 CPU 编译该程序,这些可执行文件将在各自的 CPU 上正常工作。

什么使系统小端或大端?

就 C 或 C++ 而言,CPU。计算机中的不同处理单元实际上可以有不同的字节序(GPU 可能是大字节序,而 CPU 是小字节序),但这有点不常见。

如果我想写一个字节序无关的C++程序,我需要考虑什么?

只要按照 C 或 C++ 的规则玩,就不必关心字节序问题。

当然,您也无法将文件直接加载到 POD 结构中。或者读取一系列字节,假装它是一系列无符号短裤,然后将其处理为 UTF-16 编码的字符串。所有这些都进入了实现定义的行为领域。

“未定义”和“实现定义”的行为是有区别的。当 C 和 C++ 规范说某些东西是“未定义的”时,它基本上意味着可能会发生各种破坏。如果您继续这样做(并且您的程序不会崩溃),您可能会得到不一致的结果。当它说某些东西由实现定义时,您将获得一致的结果该实现

如果您在 VC2010 中为 x86 编译,当您假装字节数组是无符号短数组(即:unsigned char *byteArray = ...; unsigned short *usArray = (unsigned short*)byteArray)时会发生什么是由实现定义的。为大端 CPU 编译时,您会得到与为小端 CPU 编译时不同的答案。

一般来说,字节序问题是您可以本地化到输入/输出系统的问题。网络、文件读取等。应该在代码库的末端处理它们。

【讨论】:

  • “extremities”,形容它的好词 :)
【解决方案2】:

系统的字节序决定了字节的解释方式,所以什么位被认为是“第一个”,什么被认为是“最后一个”。

只有在从程序外部的某些来源(如磁盘或网络)加载或保存时,您才需要关心它。

【讨论】:

    【解决方案3】:

    首先要澄清的是,字节序是硬件属性,而不是软件/操作系统属性,因此 WinXP 和 Linux 不是大端或小端,而是它们运行的​​硬件是大端或小端。

    字节序是对字节存储在数据类型中的顺序的描述。大端系统首先存储最重要的(读取最大值)值,而小端系统首先存储最不重要的字节。不必让每个数据类型与系统上的其他数据类型相同,这样您就可以拥有混合端系统。

    小端程序不会在大端系统上运行,但这与可用的指令集有关,​​而不是编译它的系统的字节序。

    如果你想编写一个独立于字节顺序的程序,你只需要不依赖于数据的字节顺序。

    【讨论】:

      【解决方案4】:

      Little-endian / big-endian 是硬件的属性。通常,为一种硬件编译的二进制代码不能在另一种硬件上运行,除非在解释机器代码并为其模拟目标硬件的虚拟化环境中。有一些双端 CPU(例如 ARM、IA-64)具有改变字节序的开关。

      就与字节顺序无关的编程而言,唯一真正需要这样做的情况是处理网络问题。有ntohl and htonl等函数可以帮助你将硬件的字节序转换为网络的字节序。

      【讨论】:

      • 感谢您提及ntohl and htonl
      【解决方案5】:

      问题 1:

      a.out 可以在 little-endian 和 big-endian 系统上运行吗?

      没有。因为a.out 已经针对它所针对的任何架构进行了编译。它不会在与其不兼容的其他架构上运行。

      但是,这个简单程序的源代码没有任何内容可能会在不同的字节序机器上中断。

      所以是的,它(源)将正常工作。 (嗯...除了void main(),你应该改用int main()

      问题 2:

      如果我的 WindowsXP 系统是 little-endian,我可以安装 big-endian VMWare/VirtualBox中的Linux系统?

      字节序是由硬件决定的,而不是操作系统。因此,无论您在其上安装什么(本机)VM,都将与主机具有相同的字节序。 (因为 x86 都是 little-endian)

      什么使系统小端或大端?

      下面是一个在 little-endian 和 big-endian 上表现不同的例子:

      uint64_t a = 0x0123456789abcdefull;
      uint32_t b = *(uint32_t*)&a;
      printf("b is %x",b)
      

      *请注意,这违反了严格别名,仅用于演示目的。

      Little Endian : b is 89abcdef
      Big Endian    : b is 1234567
      

      在 little-endian 上,a 的低位存储在最低地址。因此,当您以 32 位整数访问 a 时,您将读取它的低 32 位。在 big-endian 上,您将读取高 32 位。

      问题 3:

      如果我想写一个与字节顺序无关的 C++ 程序,我该怎么做 需要考虑吗?

      只需遵循标准 C++ 规则,不要做任何像我上面展示的示例那样丑陋的事情。避免未定义的行为,避免类型双关...

      【讨论】:

      • 从技术上讲,字节顺序永远不会在操作系统级别确定(除非它是虚拟操作系统)。
      • 这主要是我所指的。从理论上讲,您可以一起模拟整个机器、硬件和操作系统 - 任何事情都可以在其中进行。
      • 如果从理论上讲,您指的是 VMWare、Virtual Box 和 Parallels 之类的东西,那么是的。 ;-) en.wikipedia.org/wiki/…
      • 感谢您提及x86 is all little-endian
      【解决方案6】:

      1:编译器的输出将取决于您提供的选项以及您是否使用交叉编译器。默认情况下,它应该在您正在编译它的操作系统上运行,而不是在其他操作系统上运行(甚至可能不是同一类型的其他操作系统;例如,并非所有 Linux 二进制文件都可以在所有 Linux 安装上运行)。在大型项目中,这将是您最不关心的问题,因为库等需要在每个系统上以不同方式构建和链接。使用适当的构建系统(如 make)可以解决大部分问题,您无需担心。

      2:虚拟机以这样一种方式对硬件进行抽象,以允许任何东西在其他任何东西中运行。操作系统如何管理它们的内存并不重要,只要它们都运行在相同的硬件上并支持正在使用的任何虚拟化模型。 Endianness 表示字节顺序;如果它是从左到右或从右到左(或其他格式)读取的。一些硬件同时支持这两种情况,并且虚拟化允许两者在这种情况下共存(尽管我不知道这会有什么用,除非理论上是可能的)。但是,Linux 可以在许多不同的体系结构上运行(以及 Windows,而不是 Ixxx),因此情况更加复杂。

      3:如果您使用原始内存(例如二进制运算符)进行操作,您可能会将自己置于依赖字节序的位置。但是,大多数现代编程都比这更高。因此,如果您遇到可能会施加基于字节序的限制的内容,您可能会注意到。如果需要,您始终可以使用预处理器实现两种字节序的选项。

      【讨论】:

        猜你喜欢
        • 2011-02-06
        • 2013-04-30
        • 2011-05-10
        • 2021-02-07
        • 2011-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-21
        相关资源
        最近更新 更多