分享
一起读《奔跑吧Linux内核(第2版)卷1:基础架构》- 大小端字节序
输入“/”快速插入内容
一起读《奔跑吧
Linux内核
(第2版)卷1:基础架构》- 大小端
字节序
飞书用户3013
2023年12月30日修改
Hello,大家好我是硬核王同学,是一名刚刚工作一年多的Linux工程师,很感谢EEWorld的本次活动,让我有机会参与评测这本和
Linux内核
相关的的这本书。
在
嵌入式
系统开发中,大小端
字节序
问题是必须重视的关键问题之一。这篇文章我们就一起来剖析一下大小端字节序的问题,深入探讨大小端字节序的概念、原因、应用以及如何解决这个问题。
一、什么是
字节序
?什么是大小端字节序?
(1)什么是
字节序
?
字节序
(
Byte Order
)指的是在多字节数据存储时,字节的顺序排列方式。它决定了数据在
内存
中的存储方式和读取方式。字节序分为两种:大端字节序(Big-Endian)和小端字节序(Little-Endian)。
在计算机中,数据是以字节(Byte)为单位进行存储和处理的。而多字节数据,例如整数、
浮点数
等,由多个字节组成。由于计算机存储器是以字节为基本单位进行寻址的,对于多字节数据的存储,就需要确定各个字节在
内存
中的存储位置。
(2)什么是大小端
字节序
?
大小端
字节序
是指在进行多字节数据存储时,字节的顺序排列方式。具体而言,大小端字节序规定了在
内存
中数据字节存储的顺序,即哪个字节保存在内存的低地址处,哪个字节保存在内存的高地址处。
大端
字节序
要求将多字节数据的高字节保存在
内存
的低地址处,低字节保存在内存的高地址处。这种排列方式类似于我们阅读数字的方式,先读高位再读低位。例如,16位整数0x1234在大端字节序中存储为0x12(高字节) 0x34(低字节)。
小端
字节序
则相反,要求将多字节数据的低字节保存在
内存
的低地址处,高字节保存在内存的高地址处。这种排列方式与大端字节序相反,先读低位再读高位。例如,16位整数0x1234在小端字节序中存储为0x34(低字节) 0x12(高字节)。
需要注意的是,大小端
字节序
只针对于多字节数据,单字节数据(如字符)在存储时不存在字节序问题,因为它们只占用一个字节。
不同的处理器架构和
操作系统
可能对
字节序
的要求不同。因此,在进行数据交互、协议通信或不同平台之间的数据传输时,需要考虑字节序的匹配问题,以确保数据的正确解析和
兼容性
。
二、大小端
字节序
的原因
大小端
字节序
的原因主要有两方面:
1.
处理器架构:不同的处理器架构对于
字节序
的要求是不同的。一些处理器架构采用大端字节序,例如Motorola 68000系列,而另一些处理器架构采用小端字节序,例如
x86
系列。这是由于处理器在设计时对于字节序的选择有不同的考虑,例如数据的读取和存储方式,
指令
的解码等。
2.
网络协议
:在网络通信中,不同的设备和平台之间需要进行数据的交互和传输。为了保证数据的正确解析和传递,网络协议通常要求统一使用一种
字节序
。因此,协议规定了具体的字节序要求,发送方在发送数据时需要按照协议规定的字节序进行字节的排列,接收方在接收数据时也需要按照相同的字节序进行解析。
总结起来,大小端
字节序
的原因主要是由于不同的处理器架构和网络通信协议对字节序的不同要求。不同的处理器架构使用不同的字节序,导致数据在不同系统之间的传递和解析可能出现问题。为了保证数据的正确解析和传输,需要统一规定一种字节序,并且在数据的发送和接收过程中进行相应的字节序转换。
三、如何判断处理器是大端模式还是小端模式?
要判断一个处理器是大端模式还是小端模式,可以使用以下两种方法:
1.
使用联合体(Union)进行
字节序
判断:联合体是一种特殊的数据结构,它的所有成员共享同一块
内存
空间,而且成员的存放顺序是所有成员都从低地址开始存放。所有可以定义一个包含一个整数和一个
字节数组
的联合体,并将整数初始化为一个已知的值。然后,通过访问字节数组的第一个元素来判断处理器的字节序。如果第一个字节是最高有效字节(高位字节),则表示处理器是大端模式;如果第一个字节是最低有效字节(低位字节),则表示处理器是小端模式。
代码块
C
#include <stdio.h>
int isLittleEndian() {
union {
int i;
char c[sizeof(int)];
} u;
u.i = 1;
return u.c[0] == 1; // 返回1表示小端模式,返回0表示大端模式
}
int main() {
if (isLittleEndian()) {
printf("Little endian\n");
} else {
printf("Big endian\n");
}
return 0;
}