【问题标题】:Does my AMD-based machine use little endian or big endian?我的基于 AMD 的机器是使用小端还是大端?
【发布时间】:2010-11-04 17:27:38
【问题描述】:

我正在学习计算机系统课程,并且我正在尝试确定,肯定,我的基于 AMD 的计算机是否是 little-endian 计算机?我相信这是因为它与 Intel 兼容。

具体来说,我的处理器是 AMD 64 Athlon x2。

我知道这在 C 编程中很重要。我正在编写 C 程序,而我正在使用的方法会受此影响。如果我在基于 Intel 的机器上运行程序(假设 is 小端机器),我试图弄清楚是否会得到相同的结果。

最后,让我问这个问题:任何和所有能够运行 Windows(XP、Vista、2000、Server 2003 等)以及例如Ubuntu Linux desktop 的机器都是小端的吗?

【问题讨论】:

    标签: c x86 intel endianness amd-processor


    【解决方案1】:

    所有 x86 和 x86-64 机器(只是 x86 的扩展)都是 little-endian。

    你可以这样确认:

    #include <stdio.h>
    int main() {
        int a = 0x12345678;
        unsigned char *c = (unsigned char*)(&a);
        if (*c == 0x78) {
           printf("little-endian\n");
        } else {
           printf("big-endian\n");
        }
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      文章Writing endian-independent code in C中列出了一种了解字节序的简单方法

      const int i = 1;
      #define is_bigendian() ( (*(char*)&i) == 0 )
      

      【讨论】:

        【解决方案3】:

        假设您安装了 Python,您可以运行这个单行程序,它将在 little-endian 机器上打印“little”,在 big-endian 机器上打印“big”:

        python -c "import struct; print 'little' if ord(struct.pack('L', 1)[0]) else 'big'"
        

        【讨论】:

          【解决方案4】:

          “英特尔兼容”不是很精确。

          英特尔曾经制造过大端处理器,尤其是 StrongARM 和 XScale。这些不使用 IA32 ISA,通常称为 x86。

          在更早的历史上,英特尔还制造了 little-endian i860 和 i960,它们也不兼容 x86。

          再往前看,x86 的前身(8080、8008 等)也不兼容 x86。作为 8 位处理器,字节序并不重要......

          如今,Intel 仍在制造双端模式的 Itanium (IA64):正常运行是大端模式,但处理器也可以在小端模式下运行。它确实可以在 little-endian 模式下运行 x86 代码,但原生 ISA 不是 IA32。

          据我所知,AMD 的所有处理器都与 x86 兼容,并带有一些扩展,例如 x86_64,因此必然是 little-endian。

          Ubuntu 可用于 x86 (little-endian) 和 x86_64 (little-endian),对于 ia64 (big-endian)、ARM(el) (little-endian)、PA-RISC (big-endian) 的端口不太完整, 尽管处理器同时支持)、PowerPC (big-endian) 和 SPARC (big-endian)。我不相信有 ARM(eb)(大端)端口。

          【讨论】:

          • 哇,感谢您提供的详细信息。这是很好的支持信息。
          • 两个小的更正:字节序对于 8 位处理器也很重要,因为某些指令涉及 16 位数量,例如地址(LDA $1234(从地址 $1234 加载一个字节)将在 6502 上编码为AD 34 12 . AMD 确实有除 x86 之外的另一种架构,它是 29000 系列 RISC 处理器,在激光打印机等嵌入式设计中非常流行。
          • @tristopia 感谢您提供的信息,我不知道所有这些。
          【解决方案5】:

          在回答您的最后一个问题时,答案是否定的。 Linux 能够在大端机器上运行,例如老一代的 PowerMac。

          【讨论】:

          • 我链接的那个发行版是否能够在大端运行。感谢您解决我的问题。
          • 我认为他们在问这些操作系统是否可以在小端机器上运行,他们可以。事实上,我认为他们必须为老一代 PowerMac 制作特殊版本,因为 PowerPC 架构是大端的。
          • 现在 Ubuntu 支持 ARM,“Ubuntu”可以在大端处理器上运行。最近的 ARM 内核可以在小端模式或大端模式下运行。
          • PowerPC 是双端的:也就是说,它们可以在大端或小端模式下运行 - see here - 只是为了保证信息的完整性。干杯
          【解决方案6】:

          您必须下载专为大端机器设计的 Ubuntu 版本。我只知道PowerPC 版本。我相信您可以找到一些具有更通用的大端实现的地方。

          【讨论】:

          • Ubuntu 的第二类端口包括 ia64、armel、hppa、powerpc 和 sparc。在较早的版本中,PowerPC 是一流的端口,并且有一个版本也支持 SPARC。
          【解决方案7】:

          下面的sn-p代码有效:

          #include <stdio.h>
          
          int is_little_endian() {
            short x = 0x0100; //256
            char *p = (char*) &x;
            if (p[0] == 0) {
              return 1;
            }
            return 0;
          }
          
          int main() {
            if (is_little_endian()) {
              printf("Little endian machine\n");
            } else printf("Big endian machine\n");
            return 0;
          }
          

          代码中的“短”整数是 0x0100(十进制为 256),长度为 2 个字节。最低有效字节为 00,最高有效字节为 01。Little endian 排序将最低有效字节放在变量的地址中。所以它只是检查变量指针指向的地址处的字节值是否为0。 如果为0,则为小端字节序,否则为大端字节序。

          【讨论】:

            【解决方案8】:
            /* by Linas Samusas  */
            
            #ifndef _bitorder 
            #define _bitorder 0x0008
            
            #if (_bitorder > 8)
            #define BE
            #else
            #define LE
            #endif
            

            并使用它

            #ifdef LE
            #define Function_Convert_to_be_16(value)  real_function_to_be_16(value)
            #define Function_Convert_to_be_32(value)  real_function_to_be_32(value)
            #define Function_Convert_to_be_64(value)  real_function_to_be_64(value)
            #else
            #define Function_Convert_to_be_16
            #define Function_Convert_to_be_32
            #define Function_Convert_to_be_64
            #endif
            

            如果 LE

            unsigned long number1 = Function_Convert_to_be_16(number2);
            

            *宏会调用真正的函数并转换为BE

            如果是

            unsigned long number1 = Function_Convert_to_be_16(number2);
            

            *macro 将被定义为单词而不是函数,并且您的数字将在括号之间

            【讨论】:

              猜你喜欢
              • 2010-09-18
              • 2011-07-22
              • 1970-01-01
              • 1970-01-01
              • 2010-11-03
              • 2011-02-06
              • 1970-01-01
              • 2013-02-27
              • 1970-01-01
              相关资源
              最近更新 更多