字节序只适用于字节顺序,而不适用于位顺序,位顺序保持不变。
原因是什么?
内存以字节为单位进行寻址。这只是一种花哨的说法,即每个地址存储一个字节。因此,您可以更改字节的顺序,而不是内存中的位。
只有在您想要将一个大值(例如一个单词)分成几个小值时,字节序才有意义。您必须决定将其放置在内存中的顺序。
只有在您要拆分多字节数量并尝试将字节存储在连续的内存位置时,字节序才有意义。但是如果您输入一个寄存器,则没有意义。寄存器只是一个32位数量(取决于您的处理器/控制器),字节序不适用于它。
对于给定计算机系统,位顺序通常遵循相同的字节顺序 - 这是真的。
了解更多信息,请访问Endianness
小端CPU通常采用“LSB 0”位编号,但大端机器中可以看到两种位编号约定。像SPARC和Motorola 68000这样的架构使用“LSB 0”位编号,而S/390、PowerPC和PA-RISC使用“MSB 0”。[2]
请参见
在现代计算机中,字节序只适用于字节的排序,而不适用于位。
回顾几年前我提出的这个问题,今天我可以举一个例子来部分回答:在通信协议中存在并且很重要的是位序。任何协议规范都需要定义当八位被推入比特流时先发送哪一位。
“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位置就处于讨论的中心(但您对处理器工程感兴趣吗?)
答案是:只要您不在硬件级别编写ROM数据,并且在通过不同的架构/协议传输数据时仅关注BYTE级别的字节序,那么这种情况是不会发生的。人们感到困惑是因为不必要的字节序戏剧化,而字节序问题正在不应该出现的地方潜伏。
至少,这就是我在这里的原因,让学生开始理解对于特定挑战/问题而言什么是重要的。如果他们已经知道了,他们就不会来这里了。大多数人只有小端或大端计算机,并且没有交叉检查的特权。他们只是不确定,通过谷歌搜索到这里,然后看到“位不可寻址”这个词,嗯...什么?这是什么意思?我应该在字节级别还是位级别上交换我的游戏数据才能在所有平台上正确读取?我仍然不知道:/ 这就是一个人会提出这样的问题的根本原因。除了技术事实“位不可寻址”之外,还有一些人没有背景来充分理解这种说法的影响。
只有在极为罕见的情况下,您实际上通过专有或借用的流读/写逻辑通过应用程序编码自己制作的(或公司指定的)二进制数据时,您才需要关心字节序。
如果不想处理字节序,请使用具有内置读/写功能的引擎/框架(如数据库、云等),或者使用纯文本,例如Json或XML。
字节序是基于字节而非位的。位不可寻址。