什么是Big Endian和Little Endian?
我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
2.什么是Big Endian和Little Endian?
在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。比如一个16进制数字0x12345678,在内存存放的方式如下:
值
|
0111,1000
|
0101,0110
|
0011,0100
|
0001,0010
|
地址
|
100
|
101
|
102
|
103
|
另一种称为big-endian,正好相反,存放在内存中最低位的数值是来自数据的最左边边部分(也就是数据的最高为部分)。比如一个16进制数字0x12345678,在内存存放的方式如下:
值
|
0001,0010
|
0011,0100
|
0101,0110
|
0111,1000
|
地址
|
100
|
101
|
102
|
103
|
比如某些文件需要在不同平台处理,或者通过Socket通信。这方面我们可以借助ntohl(), ntohs(), htonl(), and htons()函数进行格式转换。
3.如何判断系统是Big Endian还是Little Endian?
在/usr/include/中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER, __BYTE_ORDER),确定其值。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。一般来说,Little Endian系统BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)为1234,Big Endian系统为4321。大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本质上说,Little Endian还是Big Endian与操作系统和芯片类型都有关系。
======================================================================
ext3 文件系统在硬盘分区上的数据是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平台上开发 ext3 相关的程序,要特别注意这一点。
谈到字节序的问题,必然牵涉到两大 CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。那么究竟什么是big endian,什么又是little endian呢?
其实big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB)。
用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示:
BigEndian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 12 |34 |56| 78 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Little Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|78 |56 |34|12 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
从上面两图可以看出,采用big endian方式存储数据是符合我们人类的思维习惯的。而little endian,!@#$%^&*,见鬼去吧 -_-|||
为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?在这里我想说说两种语言。C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而 JAVA编写的程序则唯一采用big endian方式来存储数据。试想,如果你用C/C++语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的 0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。
无独有偶,所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。
不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序
最常见的有两种
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
LE little-endian
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位
BE big-endian
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去
例子:在内存中双字0x01020304(DWORD)的存储方式
内存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04
例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
big-endianlittle-endian
0x00000x120xcd
0x00010x230xab
0x00020xab0x34
0x00030xcd0x12
x86系列CPU都是little-endian的字节序.
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
为了进行转换 bsd socket提供了转换的函数 有下面四个
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序
在使用little endian的系统中 这些函数会把字节序进行转换
在使用big endian类型的系统中 这些函数会定义成空宏
同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.
注:
1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。
处理器操作系统字节排序
Alpha全部Little endian
HP-PANTLittle endian
HP-PAUNIXBig endian
Intelx86全部Little endian <-----x86系统是小端字节序系统
Motorola680x()全部Big endian
MIPSNTLittle endian
MIPSUNIXBig endian
PowerPCNTLittle endian
PowerPC非NTBig endian<-----PPC系统是大端字节序系统
RS/6000UNIXBig endian
SPARCUNIXBig endian
IXP1200 ARM核心全部Little endian
分享到:
相关推荐
Big Endian & Little Endian.pdf Big Endian & Little Endian.pdf
nohead data big endian to little endian
little endian和big endian的概念解释
比较详细的介绍了大小端问题。嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。
this pdf is for big endian little endian concept useful for application devloper
对于大于十进制255(16进制0xff)的整数,需要多个存储单元。例如,4660对应于0x1234,需要两个字节。不同的计算机系统使用不同的方法保存这两个字节。...前一种就被称为Little Endian,后一种就是Big Endian。
little endian,big endian 小端存储、大端存储.zip
大端(Big_Endian)与小端(Little_Endian)简介
大端(Big Endian)与小端(Little Endian)简介
基于STM32HAL库,USART-调试串口(大小端测试),对应文章:https://blog.csdn.net/qq_36075612/article/details/115935138?spm=1001.2014.3001.5501
你是否遇到过,内存中的数据顺序颠倒 你存入1234,实际存储的是3412. 字节存储顺序: little-endian小端,big-endian大端 教程 主机序,网络序 hton,ntoh
buffer ) ) [ 0 ] === 0x04030201 )用法使用 npm 安装: npm install is-little-endian然后像这样使用它: if ( require ( "is-little-endian" ) ) { // Use little endian buffer} else { // Use big endian ...
西门子PLC接口,大端和小-Endian的存储格式pdf,西门子PLC接口,大端和小-Endian的存储格式:本文介绍了SINUMERIK:PLC接口,和Little-Endian的Big-Endian的存储格式
请写一个C函数,若处理器是Big_endian的,则返回 0;若是Little_endian的,则返回1。 • 函数原型:int checkCPU( );
现代处理器的流水优化方法介绍,对于做优化的特别有用
包含little-endian、big-endian算法,已及相应的查表算法。 此外,还专门针对cksum、hashcalc这两个常见的校验软件,写了计算例子。 如果还在疑惑为什么cksum和crc32、hashcalc的结果不一样,建议看一下这个程序。
数据库文件的格式是跨平台的,你可以在32位和64位系统之间、甚至在Big-Endian和Little-Endian(译者注:这是两种不同的字节排序方式,Big-Endian是指一个word中的高位Byte是放在内存word区域的低地址处,而Little-...
探寻big endian little endian 的最原始文章,熟悉字节存储机制不可或缺的资料~~
字节序 用于字节序检测和操作的 C++ 头文件库 从stackoverflow上的可爱评论中提取 ... bool should_swap = IsBigEndian(); /* ... */ if (should_swap) { i = swap_endian(i); } 添加一名作者 许可证:麻省理工学院
大端(Big Endian)与小端(Little Endian)详解 - 凌风探2016年4月2日 - 大端(BigEndian)与小端(LittleEndian)简介///1.你从哪里来?端模式(Endian)的... 将鸡蛋敲开的人被归为BigEndian从尖头开始将鸡蛋敲开的人被归为...