字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。
其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。
在所有的介绍字节序的文章中都会提到字节序分为两类:Big-Endian和Little-Endian。引用标准的Big-Endian和Little-Endian的定义如下:
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
c) 网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序。由于 TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序。比如,以太网头部中2字节的“以太网帧类型”,表示后面数据的类型。对于ARP请求或应答的以太网帧类型来说,在网络传输时,发送的顺序是0x08,0x06。
栈底 (高地址)
---------------
0x06 -- 低位
0x08 -- 高位
---------------
栈顶 (低地址)
该字段的值为0x0806。按照大端方式存放在内存中。
------------------------
|高地址:命令行参数和环境变量
----------------------- 0xC0000000 X86处理器
| 栈底
|
| 栈
|
|
|
\|/
NULL (空洞)
/|\
|
|
| 堆
-----------------------
未初始化的数据:由EXEC初始化为0或空指针 BSS
----------------(统称数据段)
初始化的数据
----------------------- :由EXEC从程序读入
正文段(代码段)
----------------------- 正文段开始:0x08048000 X86处理器
现在我们弄清了高低地址,接着来弄清高/低字节,如果我们有一个32位无符号整型0x12345678(呵呵,恰好是把上面的那4个字节buf看成一个整型),那么高位是什么,低位又是什么呢?其实很简单。在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。
高低地址和高低字节都弄清了。我们再来回顾一下Big-Endian和Little-Endian的定义:
以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value:
Big-Endian: 低地址存放高位
栈底 (高地址)
---------------
buf[3] (0x78) -- 低位
buf[2] (0x56)
buf[1] (0x34)
buf[0] (0x12) -- 高位
---------------
栈顶 (低地址)
Little-Endian: 低地址存放低位
栈底 (高地址)
---------------
buf[3] (0x12) -- 高位
buf[2] (0x34)
buf[1] (0x56)
buf[0] (0x78) -- 低位
---------------
栈顶 (低地址)
在现有的平台上Intel的X86采用的是Little-Endian,而像Sun的SPARC采用的就是Big-Endian。
三、例子
嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。
例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 存放内容
0x4001 0x12
0x4000 0x34
而在Big-endian模式CPU内存中的存放方式则为:
内存地址 存放内容
0x4001 0x34
0x4000 0x12
32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 存放内容
0x4003 0x12
0x4002 0x34
0x4001 0x56
0x4000 0x78
而在Big-endian模式CPU内存中的存放方式则为:
内存地址 存放内容
0x4003 0x78
0x4002 0x56
0x4001 0x34
0x4000 0x12
分享到:
相关推荐
对字节序的一些理解。
判断主机到底是大端还是小端的c程序!利用位置判断
大小端字节序的介绍和相互转换。在c++中,有4个函数可以实现主机字节序到网络字节序的相互转换。
字节序 大小端 网络编程 字节序 大小端 网络编程
字节序转换辅助类,short大小端转换,ushort大小端转换,int大小端转换,uint大小端转换,long大小端转换,ulong大小端转换; short类型 小端转大端,short类型 大端转小端,int类型 小端转大端,int类型 大端转小端...
提供一个大小端转换的类,可以转换short int float double类型,提供一个大小端转换的类,可以转换short int float double类型,提供一个大小端转换的类,可以转换short int float double类型
TIA博途-32位浮点数大小端存储-高低字节转换的具体方法示例(4种字节排列顺序)
判断网络字节序大小端简易程序,tcp连接监听...(Linux高性能网络编程第三版第五章源码)
1、大小端的概念;2、结构体和联合体存储方式;3、位域的概念。
其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。
大小端模式对C语言的共用体结构的影响:当共用体中有不同类型的变量,用一种变量类型给共用体赋值...比如在问题1中,给int类型的变量i赋值,但通过char类型的数组来读取时,就要注意字节序的问题,也就是大小端的问题。
2.2 存储空间的高地址字节 与 低地址字节 2.3 大端序存储和小端序存储 2.4 测试计算机的大小端序 2.5 通信中的大小端序
4、新增“运算_大小端转换”,大小端字节序转换;。5、新增“类_json - 取所有属性值”,取指定路径下所有属性的值;。6、新增“窗口_取标题W”,获取指定窗口句柄的Unicode标题;感谢【@mrzcpo 】建议;。7、新增...
(1)、多态的类,内存布局是怎样 (3)、unordered_set 的底层数据结构 (4)、隐式类型转换与显示类型转换 (6)、大小端字节序相关 (7)、手写
co_endian 大小端字节序的转换 网络库 co_timingwheel 基于时间轮的高效定时器 co_timerservice 定时器服务 co_routine 高效协程库,基于少量汇编的快速执行环境切换 co_loop/co_poll/co_ioservice 封装epoll/kqueue...
文档包括内容。 (1). C函数类型转换相关。 [1] 理解C函数类型转换。 [2] C函数类型转换使用不当会导致程序运行出错的场景。 [3] C程序调用未声明函数,一种无...(2) 大小端-字节序问题。 (3) 权衡使用寄存器指针变量。
内容丰富,从网络基本模型,数据的封装与解包,域名解析,大小端字节序,到socket编程,更有诸多源代码,可供深入研究。
字节序(Endianness):大端和小端 二、应用 结构体是一种数据的归类方式,相比数组或变量更具有整体全面性,例如一个数组只可以放一些按照元素顺序存放的单元变量,即 buffer = {x, x, x, x, x…},i 有多大,数组...