绪论
字节顺序,又称
端序
或
尾序
(英语:Endianness),在计算机科学领域中,指电脑内存中或在数字通信链路中,组成多字节的字的字节的排列顺序。
字节的排列方式有两个通用规则。例如,将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称
小端序
;反之则称
大端序
。在网络应用中,字节序是一个必须被考虑的因素,因为不同机器类型可能采用不同标准的字节序,所以均按照网络标准转化。
1、端(endian)的起源
“endian”一词来源于十八世纪爱尔兰作家乔纳森·斯威夫特(Jonathan Swift)的小说《格列佛游记》(Gulliver’s Travels)。小说中,小人国为水煮蛋该从大的一端(Big-End)剥开还是小的一端(Little-End)剥开而争论,争论的双方分别被称为“大端派(Big-Endians)”和“小端派(Little-Endians)”。以下是1726年关于大小端之争历史的描述:
“我下面要告诉你的是,Lilliput和Blefuscu这两大强国在过去36个月里一直在苦战。战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端,可是当今皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了。因此他的父亲,当时的皇帝,就下了一道敕令,命令全体臣民吃鸡蛋时打破鸡蛋较小的一端,违令者重罚。老百姓们对这项命令极其反感。历史告诉我们,由此曾经发生过6次叛乱,其中一个皇帝送了命,另一个丢了王位。这些叛乱大多都是由Blefuscu的国王大臣们煽动起来的。叛乱平息后,流亡的人总是逃到那个帝国去寻求避难。据估计,先后几次有11000人情愿受死也不肯去打破鸡蛋较小的一端。关于这一争端,曾出版过几百本大部著作,不过大端派的书一直是受禁的,法律也规定该派任何人不得做官。”
——《格列夫游记》 第一卷第4章 蒋剑锋(译)
1980年,丹尼·科恩(Danny Cohen),一位网络协议的早期开发者,在其著名的论文”On Holy Wars and a Plea for Peace”中,为平息一场关于字节该以什么样的顺序传送的争论,而第一次引用了该词。
2、字节序
在哪种字节顺序更合适的问题上,人们表现得非常情绪化.实际上不管是大端序或小端序各有其优缺点。
对于单一的字节(a byte),大部分处理器以相同的顺序处理位元(bit),因此单字节的存放方法和传输方式一般相同。对于多字节数据,如整数(32位机中一般占4字节),在不同的处理器的存放方式主要有两种,以32位的寄存器为例,分别有以下几种方式(verilog作为演示):
【示例】
......
reg [31:0] data;
......
initial data = 32'h12345678
......
大端序
大端序
(英:big-endian)或称
大尾序
。
- 低地址存放高位数据
高位地址 |
addr[3] |
data[7:0] |
8’h78 |
---|---|---|---|
addr[2] |
data[15:8] |
8’h56 |
|
addr[1] |
data[23:16] |
8’h34 |
|
低位地址 |
addr[0] |
data[31:24] |
8’h12 |
小端序
小端序
(英:little-endian)或称
小尾序
。
- 低地址存放数据低位
高位地址 |
addr[3] |
data[31:24] |
8’h12 |
---|---|---|---|
addr[2] |
data[23:16] |
8’h34 |
|
addr[1] |
data[15:8] |
8’h56 |
|
低位地址 |
addr[0] |
data[7:0] |
8’h78 |
混合序
混合序
(英:middle-endian)具有更复杂的顺序。
如下表所示,可以看作高16bit和低16bit以大端序存储,但16bit内部以小端存储。
高位地址 |
addr[3] |
data[15:8] |
8’h56 |
---|---|---|---|
addr[2] |
data[7:0] |
8’h78 |
|
addr[1] |
data[31:24] |
8’h12 |
|
低位地址 |
addr[0] |
data[23:16] |
8’h34 |
3、处理器体系
-
x86
、
MOS Technology 6502
、
Z80
、
VAX
、
PDP-11
等处理器为小端序; -
Motorola 6800
、
Motorola 68000
、
PowerPC 970
、
System/370
、
SPARC
(除V9外)等处理器为大端序; -
ARM
、
PowerPC
(除PowerPC 970外)、
DEC Alpha
、
SPARC V9
、
MIPS
、
PA-RISC
及
IA64
的字节序是可配置的。
4、网络序
网络传输一般采用大端序,也被称之为
网络字节序
,或
网络序
。
IP
协议中定义大端序为网络字节序。
Berkeley套接字
定义了一组转换函数,用于16和32bit整数在网络序和
本机字节序
之间的转换。htonl,htons用于本机序转换到网络序;ntohl,ntohs用于网络序转换到本机序。
5、位序
一般用于描述串行设备的传输顺序。
网络协议
中只有
数据链路层
的底端会涉及到。
小端序(先传低位)的串行协议
大端序(先传高位)的串行协议
6、大端序与小端序的优点
小端序优点
:
-
内存的低地址处存放低字节,所以在强制转换数据时不需要调整字节的内容。
-
CPU做数值运算时从内存中依顺序依次从低位到高位取数据进行运算,直到最后刷新最高位的符号位,这样的运算方式会更高效。
大端序优点
:
- 符号位在所表示的数据的内存的第一个字节中,便于快速判断数据的正负和大小。
7、总结
实际上目前很多cpu访存是以小端序的方式,例如典型的risc-v架构的蜂鸟e203。记住大端序与小端序的存储方式其实很容易,只需记住小端序低地址存放数据低位,是一种对应的关系。而大端序的存储与小端序相反
8、引用
1、
字节顺序 – 维基百科,自由的百科全书 (wikipedia.org)
2、
Verilog系列:大小端_技术交流_牛客网 (nowcoder.com)