【问题标题】:Does endianness apply to bit order too?字节序是否也适用于位顺序?
【发布时间】:2014-10-13 15:43:36
【问题描述】:

我在这里没有找到关于 SO 的具体问题,如果这是重复的,请指出给我,我会删除它。

真的,字节序与顺序有什么关系吗?

This 似乎暗示答案是否定的,而其他来源(我现在找不到,但肯定我前段时间读过一些文章)暗示字节顺序是 字节和位

更具体地说:在 Big Endian 架构中,在任何字节内,MSB 是第一位的,MSB 也是第一位的吗?反之,在 LSB 在前的 Little Endian 系统上,LSb 也是在前吗?

最后编辑:我发现 this 说“位顺序通常遵循与给定计算机系统的字节顺序相同的字节顺序

【问题讨论】:

  • 我认为现在选择一个解决方案是合适的,因为这里似乎有几个人给出了经过深思熟虑的答案。
  • @user2752635 但所有这些答案都不好!

标签: c endianness


【解决方案1】:

其他回答并不完全准确。是的,内存是字节可寻址的,所以通常字节序会停在那里。但可寻址性并不是创建明确定义的字节序的唯一方法。

在 C 中,您可以定义位域。位域有特定的布局;例如,第一个位字段(如果是一个位)可以存储在 msb 或 lsb 中,并且以大端方式跨字节边界包装位字段与以小端方式进行包装截然不同。所以如果你定义位域,你可能会有位字节序。

但如何安排这些与编译器有关,而不是与体系结构有关,至少通常是这样。

【讨论】:

    【解决方案2】:

    不,只是因为您不能单独寻址位。

    【讨论】:

    • 在硬件级别(串行端口)工作时,位字节序是相关的..它被称为位字节序..
    • 结构中的位域呢?
    • @mafso,字节仍然是最小的可寻址实体,这意味着编译器将不得不使用位移运算符来访问结构中的位域。
    • 找到了。 C11 (n1570) 6.7.2.1 p.11 单元内的位域分配顺序(高位到低位或低位到高位)由实现定义。当然,您必须关心的情况很少见,但确实存在。
    • 即使您无法寻址位,但知道位仍然以某种模式排序(即,一位被认为比其他位更重要)是有用的。 en.wikipedia.org/wiki/Bit_numbering
    【解决方案3】:

    字节序仅适用于字节顺序。不适用于位顺序。位顺序保持不变。

    为什么?

    内存是字节可寻址的。这只是一种奇特的说法,即每个地址存储一个字节。所以你可以改变字节的顺序,而不是内存中的位。

    只有当您想将一个较大的值(例如一个单词)分解为几个较小的值时,字节序才有意义。您必须决定将其放入内存的顺序。

    字节序仅在您分解多字节数量并尝试将字节存储在连续内存位置时才有意义。但是如果你接受一个寄存器,它就没有意义了。寄存器只是一个 32 位的数量(取决于您的处理器/控制器),字节顺序不适用于它。

    位顺序通常遵循与给定计算机系统的字节顺序相同的字节顺序 - 这是真的

    欲了解更多信息Endianness

    【讨论】:

      【解决方案4】:

      在现代计算中,字节序仅适用于字节排序,而不适用于位。

      【讨论】:

        【解决方案5】:

        Little-endian CPU 通常使用“LSB 0”位编号,但是在 big-endian 机器中可以看到这两种位编号约定。一些架构,如 SPARC 和 Motorola 68000 使用“LSB 0”位编号,而 S/390、PowerPC 和 PA-RISC 使用“MSB 0”。[2]

        请看

        http://en.wikipedia.org/wiki/Bit_numbering

        http://en.wikipedia.org/wiki/Most_significant_bit

        【讨论】:

          【解决方案6】:

          回顾我几年前提出的这个问题,今天我可以添加一个部分响应,其中包含位字节序存在且很重要的示例:在通信协议中。任何协议规范都需要定义在将八位字节推入比特流时首先发送哪个比特。

          【讨论】:

          • 确实如此,但这与架构有什么关系?例如,JTAG 需要以位为单位传输数据;当沿 JTAG 链敲入位时,您必须将其移入小端(因为它从 MS 位侧移入)。但是,此要求与您的架构或编译器无关;无论您使用的是 32 位 Pentium 2 还是使用大端序的 64 位电源 PC,JTAG 位都以小端序发送。
          • 与架构无关。我刚刚提到它作为一个示例,其中位字节序可能与计算系统相关(请参阅我的问题标题)。
          • 在您的问题中,我正在阅读以“更具体”而不是“例如”开头的段落。
          • (仅供参考,我并不是说这不是您想要的,而是 if 是,那么您的问题与您的预期问题不符并且应该澄清)。
          【解决方案7】:

          字节序基于字节而不是位。位不可寻址。

          【讨论】:

            【解决方案8】:

            “bits are not addressable”是什么意思对于傻瓜(比如我和我的学生)?

            计算机可以存储/移动/更改的最小值/实体是一个字节 = 8 位。您不能指示它读/写 3 位,然后 1 位,然后 11 位,并告诉计算机将它们作为单独的值存储。不,它只处理单个字节或字节包/范围。

            然后,任何应用程序/进程/硬件都可以使用字节内的位(或本机整数类型,总是字节的倍数)。

            然而,一旦播放完毕,内存/存储中存储的值仍然是字节的“范围”,每个单独的 BYTE 值 - 尽管它们的位被修改 - 都会在 BYTE 级别直接更新为它们的新值

            这意味着,除非你构建处理器,你实际上只处理字节,0-255,句号。

            在记录中?是的。内存地址?是的。文件数据/流?是的。网络传输?是的,该死的!

            例如:假设我在 我的 LittleEndian 计算机上,在我的应用程序的内存中有 3 字节(24 位)记录:

            structure Test24 {
                var16 : 0xC1D3, // 49619 = 1100 0001 1101 0011
                var8  : 0xCA    //   202 = 1100 1010
            }
            

            记录我将 raw 保存在一个文件中,然后在他的 BigEndian 机器 上将其传递给好友。在同一应用程序中加载记录后,他在机器上得到的是:

            structure Test24 {
                var16 : 0xD3C1, // 54209 = 1101 0011 1100 0001 (bytes swapped)
                var8  : 0xCA    //   202 = 1100 1010 (same value)
            }
            

            var16 略有不同(已损坏),但那是因为我没有编写应用程序来处理 BigEndian 架构上的 IO 数据。尽管位被完全交换,但他没有得到以下记录:

            structure Test24 {
                var16 : 0xCB83, // 52099 = 1100 1011 1000 0011 (bits swapped)
                var8  : 0x53    //    83 = 0101 0011 (different value)
            }
            

            ^^ 这是因为文件是逐字节读取的,而不是逐位读取的。

            这就是“位不可寻址”的含义。


            学生:但是为什么人们喜欢 LSBit (LSB-0)、MSBit,有时还有位字节序,比如 “这是非常重要的知识”

            因为这种调用位的方式实际上消除了等式中的字节顺序问题。以正确的方式使用事物的含义,至少,使用逻辑。当我们混淆谈论数据和谈论(处理器)架构时,就会产生误解。他们 - 未重新发布!

            数据需要上下文,例如“此地址的此字节包含定义您在系统上的访问权限的八个标志”。这不是字节序问题,这就是给定索引的位在定义数据的上下文中的用途。

            我们人类被训练成横向阅读。但问题来了:

            What is byte 241 ? How we may represent what it contains ?
            perhaps on little endian, LSB-0 on the left (?)
            bit index : 0, 1, 2, 3, 4, 5, 6, 7 => 10001111b ?
            or on big endian, LSB-0 on the right (?)
            bit index : 7, 6, 5, 4, 3, 2, 1, 0 => looks more intuitive 11110001b
            
            STOP SHOOTING YOURSELF IN THE FOOT ! Consider looking at it this way :
            LSB 0 <- see : here it is, it doesn't matter where it is, it's just there
                1
                2
                3
                4
                5
                6
            MSB 7 <- and here the other one, on the opposite side.
            
            or this way :
            MSB 7
                  6
                    5
                      4
                        3
                          2
                            1
                              0 LSBit
            

            LSB-0 MSBit 在哪里并不重要,只要一个在另一个的对面。让字节序不碍事!使用 LSB-0 术语来修复数据编码的开始。

            ^^ 现在当你定义 “数据标志顺序从 LSB-0 开始”,标志是,“目录打开,打开密码保护,目录复制,复制密码保护,目录write, write pwd protected, directory delete, delete pwd protected”,意思是:

            LSB 0 directory open
                1 open pwd protected
                2 directory copy
                3 copy pwd protected
                4 directory write subitem
                5 write to pwd protected
                6 delete subitem
            MSB 7 delete pwd protected
            

            所以241 = LSB-0 : 1, 0, 0, 0, 1, 1, 1, MSB : 1的字节值意味着

            LSB 0 = 1 -> you can open directory
                1 = 0 -> directory access is not password protected
                2 = 0 -> you cannot copy directory
                3 = 0 -> noop
                4 = 1 -> you may create files or sub directories
                5 = 1 -> but a password is required to create file or dir
                6 = 1 -> you may delete the things in the directory
            MSB 7 = 1 -> but a password is required to delete
            

            在数据方面不涉及位级别的字节序,当您为字节的值赋予含义时,只有位位置很重要,并且 LSB-0 始终为 0x01,无论是大端机器还是小端序。

            字节值与机器如何处理比特无关,无论是否最重要。所以当你问“我的数据会损坏吗?”时,没有人应该在左边或右边谈论 MSBit 或 LSBit。如果你问“这个 CPU 上最不稳定的位是什么?”,你去吧,LSB/MSB 位置就在谈话的中间(但是你是处理器工程的吗?) p>


            • 这里的实际 SO 问题不是假设大多数架构的行为方式(内存寻址),或者可以/不能这样做,我们应该询问 Theorical Computer ScienceSoftware Engineering
            • 真正的根本问题是何时我的应用程序生成的数据,何时通过networkIOCOM、硬件等,交换位,或者当我未能在我的应用程序中处理位顺序时损坏。

            答案是:这不会发生,只要您不在硬件级别写入 ROM 数据,并且在通过不同架构传输数据时只关心字节级别的字节序/协议。人们因为不必要的字节序戏剧而感到困惑,而字节序的东西潜伏在不应该的地方。


            至少,这就是我来这里的原因,让学生们开始了解对于给定的挑战/关注点来说什么是重要的。如果他们已经知道,他们就不会在这里。大多数人只有小端计算机或大端计算机,没有交叉检查的特权。他们只是不确定,他们是通过谷歌到达这里的,“位不可寻址” errrmm...什么?那是什么意思 ?我是否应该以字节或位级别交换我的游戏数据以在所有平台上正确读取?我仍然不知道:/这就是人们会问的根本原因。除了“位不可寻址”这一技术事实之外,还有一些人不具备完全理解这种说法的含义的背景。

            只有在极少数情况下,您才需要关心字节序,您实际上是通过您的应用程序通过您的专有或借用的流读/写逻辑对您自己制作的(或公司指定的)二进制数据进行编码。

            不想处理字节顺序,使用具有内置读/写功能的引擎/框架(如数据库、云等)或使用 Json 或 XML 等纯文本。

            【讨论】:

              猜你喜欢
              • 2011-11-03
              • 2020-11-27
              • 2016-06-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-02-12
              • 2013-05-24
              相关资源
              最近更新 更多