字节序是否也适用于位序?

17

我在SO上没有找到一个特定的问题,如果这是重复的,请指出来,我会删除它。

那么,字节序与顺序有关吗?

这篇文章似乎暗示了答案是否定的,而其他一些来源(我现在找不到,但我肯定曾经读过一些文章)则暗示字节序是字节和位的顺序。

更具体地说,在大端架构中,其中MSB位于首位,任何字节内部,MSb也是首位吗?相反,在小端系统中,其中LSB位于首位,LSb也是首位吗?

最后编辑:我发现这篇文章说“位顺序通常遵循计算机系统给定的字节顺序的字节顺序”。


1
我认为现在选择一个解决方案是合适的,因为这里似乎有几个人给出了深思熟虑的答案。 - Thomas
@user2752635 但是所有这些答案都很糟糕! - foobarbecue
8个回答

9
其他回答并不完全准确。是的,内存是以字节为单位寻址的,所以通常字节序在这里就停止了。但是,可寻址性并不是创建良好定义的字节序的唯一方式。
在C语言中,您可以定义位域。位域具有特定的布局;例如,如果一个位域只有一位,则第一个位域可以存储在msb或lsb中,并且以大端方式跨越字节边界包装位域与以小端方式不同。因此,如果您定义位域,则可能会出现位字节序。
但是,这些如何排列更多地与编译器有关,至少按照规则是如此,而不是体系结构。

5

字节序只适用于字节顺序,而不适用于位顺序,位顺序保持不变。

原因是什么?

内存以字节为单位进行寻址。这只是一种花哨的说法,即每个地址存储一个字节。因此,您可以更改字节的顺序,而不是内存中的位。

只有在您想要将一个大值(例如一个单词)分成几个小值时,字节序才有意义。您必须决定将其放置在内存中的顺序。

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

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

了解更多信息,请访问Endianness


4
不行,因为你无法单独地址位。

3
在硬件层面上(串口)工作时,位序大小端是相关的,并被称为位序大小端。 - odedsh
4
结构体中的位域怎么处理? - mafso
@mafso,字节仍然是最小可寻址实体,这意味着编译器将不得不使用位移操作符来访问结构体中的位字段。 - doron
5
找到了。C11 (n1570) 6.7.2.1页第11行:“单元内位域的分配顺序(从高位到低位或从低位到高位)是由实现定义的。” 当然,需要关注的情况很少,但确实存在。 - mafso
2
尽管您无法直接寻址位,但了解位仍按特定模式排序(即一个位被认为比其他位更重要)仍然很有用。https://en.wikipedia.org/wiki/Bit_numbering - Thomas
显示剩余3条评论

2

2

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


2

回顾几年前我提出的这个问题,今天我可以举一个例子来部分回答:在通信协议中存在并且很重要的是位序。任何协议规范都需要定义当八位被推入比特流时先发送哪一位。


这当然是真的,但这与架构有什么关系呢?例如,JTAG需要以位为单位进行数据传输;在沿着JTAG链敲入位时,必须按照小端序列(因为它从MS位侧面移位)。然而,这个要求与您的架构或编译器无关;无论您使用32位Pentium 2还是64位大端序列的power pc,JTAG位都是以小端序列发送的。 - H Walters
1
与架构无关,我只是举了一个例子,展示位序可能与计算系统有关(请参见我的问题标题)。 - Bogdan Alexandru
在你的问题中,我读到了一个以“更具体地说”开头而不是“例如”的段落。 - H Walters
(请注意,我并不是在争论这不是你的本意,而是如果这是你的本意,那么你目前的问题与你的本意不符,应该澄清。) - H Walters

0

“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
}

我将保存的“原始”记录存入文件,并传递给我的朋友,他使用的是“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 开始排序",这些标志包括 "打开目录、打开密码保护、复制目录、复制密码保护、写入目录、写入密码保护、删除目录、删除密码保护",那就意味着:

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位置就处于讨论的中心(但您对处理器工程感兴趣吗?)


  • 这里实际的问题不是大多数架构被认为会如何行动(内存寻址),或者可以/不能做到,我们应该在理论计算机科学软件工程上提问。
  • 真正的根本问题是我的应用程序产生的数据通过网络IOCOM硬件等进行传输时,是否会发生位交换或者在我没有处理应用程序中的位顺序时出现损坏。

答案是:只要您不在硬件级别编写ROM数据,并且在通过不同的架构/协议传输数据时仅关注BYTE级别的字节序,那么这种情况是不会发生的。人们感到困惑是因为不必要的字节序戏剧化,而字节序问题正在不应该出现的地方潜伏。


至少,这就是我在这里的原因,让学生开始理解对于特定挑战/问题而言什么是重要的。如果他们已经知道了,他们就不会来这里了。大多数人只有小端或大端计算机,并且没有交叉检查的特权。他们只是不确定,通过谷歌搜索到这里,然后看到“位不可寻址”这个词,嗯...什么?这是什么意思?我应该在字节级别还是位级别上交换我的游戏数据才能在所有平台上正确读取?我仍然不知道:/ 这就是一个人会提出这样的问题的根本原因。除了技术事实“位不可寻址”之外,还有一些人没有背景来充分理解这种说法的影响。

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

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


位移操作怎么样?它们特别是左移或右移,所以你需要关注位的顺序,对吧? - Jez
@Jez:实际上,你有两个字节序层,一个是硬件层面的,即组件内部的电子物理配置,另一个是数据/值层面,这是我们应该关注的虚拟化、抽象化的组件输出、处理器或系统的值,也就是你正在操作的值,存在于内存/屏幕中的值。0x01=1的值应该始终表示为00000001b,即MSB,这是一种广泛使用的约定,使人类大脑更容易可视化,但实际上并没有任何几何形状。因此,当你向左移动时,它变成了0x02,但这都是一个想象的概念。 - Karl Stephen
试图在非物理概念上强制执行几何布局是非常令人困惑的。如果你从事组件工程,显然你必须设计电子如何转换为ROM/处理器/内存/代码中可用的值:你要设计一个LSB组件,也就是说,通过设计,将抽象值0x01(数据侧)翻译成将电子存储为0x80,但组件仍必须输出值0x01。组件如何管理做到这一点,我们不关心。只要你不超出组件/系统领域,这种方法就有效。不要被两个层次弄混了。 - Karl Stephen
现在,在数据级别上,MSB/LSB有什么意义呢?因为世界从一开始就没有达成硬件规范的共识,LSB或MSB,你两者都有。所以,当你在系统之间交换信息时,比如通过网络电线,因为通过将你的值编码为字节流(电子)存储在内存中,那么位可能会被交换,不是因为你的字节数组的值级别存在位几何,而是因为你的字节数组已经被一个组件转换为特定的电子配置,并由另一个组件转换回一个想象中的字节数组。你开始理解了吗? - Karl Stephen
当您意识到在不支持本地字节顺序的不同系统之间交换数据时,您需要有意地将虚假值序列化为兼容的电子配置输出端,通过交换(虚拟化、想象、实际上不存在的概念)位。这是一件事情。使用移位、或/和/xor操作来操作位,以便该值具有意义并可供人类使用,则是另一回事:如果您需要“位”按特定顺序排列,则具有位位置的概念表示有所帮助(MSB)。 - Karl Stephen
不要混淆,首先定义你正在处理的内容,如果你有风险在数据级别与不同系统交互。如果你只是使用int、bool和string,而没有对任何东西进行编码/序列化,在系统字节顺序的边界内,就不必担心。如果你使用位标志,将值解释为MSB几何,并相应地使用位操作工具。如果你超出了系统字节顺序,无论何时都要交换位。如果你正在设计组件,请确保无论你如何编写/操作电子,都输出预期的值。 - Karl Stephen

0

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


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