计算机存储体系结构之大小端存储格式
2013-07-14 12:35
405 查看
目前在计算机存储体系中通常采用的字节存储机制主要有两种:
big-edian 和 littile-endian。
本文简要描述这两种存储机制的特点与区别。
为了叙述方便,下面先对本文中简要用到的两个疏于进行简单定义
1.MSB是Most Significant Bit/Byte 的首字母缩写,通常译为最重要位或者最重要的字节。它通常用来表明在一个bit序列或者一个字节序列中对整个序列影响最大的位或者字节
2.LSB是Least Significant Bit/Byte 的首字母缩写,通常译为最不重要的位或者最不重要的字节,它通常用来表明在一个bit序列或者一个字节序列中对整个序列影响最小的位或者字节
3.big-endian:计算机体系结构中的一种描述多字节存储顺序的术语,在这种机制中最重要的字节(MSB)存放在最低端的地址上。如下:
双字节数0x1234以big-endian的方式存在起始地址0x00000020中
+--------------------------+ | 0x34 |<-- 0x00000021
+--------------------------+ | 0x12 |<-- 0x00000020
在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0X8B8A为例)
Big-Endian的bit序列编码方式
bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +------------------------------------------------+
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 | +-------------------------------------------------+
^ 0x8B 0x8A ^
MSB
LSB
注一:通常在TCP/IP协议中所说的网络序列(Network Order)就是使用Big-Endian规则。在TCP/IP网络通信中,通信双方把消息按照上面图方式编码,然后按照从MSB(bit0)到LSB(bit15)的顺序在网络上传输。
4.little-endian:计算机体系结构中一种描述多字节存储的术语,在这种机制中最不重要的字节(LSB)存放在最低端的地址上,通常用来描述一个字节中各个比特的排放次序。
双字节数0x1234以little-endian的方式存在起始地址0x00000020中
| 0x12 |<-- 0x00000021 +---------------------------+
| 0x34 |<-- 0x00000020 +---------------------------+
在Little-Endian中,对于bit序列中的序号编排和Big-Endian刚好相反,其方式如下(以双字节数0x8B8A为例):
Little-Endian的bit序列编码方式
bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----------------------------------------+
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 | +-----------------------------------------+
^ 0x8B 0x8A ^
MSB LSB
通常我们说的主机序(Host Order)就是使用Litlle - Endian规则。所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序(Little-Endian)到网络序(Big-Endian)的转换。
什么是字节序?
字节序:顾名思义,就是多个字节类型的数据在内存中存放的顺序,在跨平台已经网络程序中字节序才是一个应该考虑的问题。
字节序的两种分类:a: Little-Endian 就是低位字节排放在内存的低地址端,高字节排放在内存的高地址端。
b.Big-Endian就是高位字节排放在内存的低地址端,低位字节拍排放在内存的高地址端。
c.网络TCP/I各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称为网络字节序。
什么是高/低地址 什么是高/低字节
C程序映像中内存空间的分布情况,在《C专家编程》中或者《UNIX环境高级编程》中有关内存的分布情况大致如下:
--------------最高内存地址 0xffffffff -------------
栈底(高地址)
栈…
栈顶(低地址)
-------------------------------------------------------
NULL (空洞)
--------------------------------------------------------
堆
------------------------------------------------------
未初始化的数据
--------------------------------------(统称数据段)
初始化的数据
-------------------------------------------------------
正文段(代码段)
---------------最低内存地址 0x00000000--------
以上图为例如果我们在栈上分配一个unsigned char buf[4],那么这个数组变量在栈上是如何布局的呢?看下图:
------栈底(高地址)-----
buf[3]
buf[2]
buf[1]
buf[0]
----栈顶(低地址)------
高低字节: 拿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-Edian。那么在跨平台或网络程序中如何实现字节序的转换?这个通过C语言的移位操作很容易实现,例如:
#if define(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
#define htons(A) (A)
#define htonl(A) (A)
#define ntohs(A) (A)
#define ntohl(A) (A)
#elseif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define htons(A) (((uint16)(A)&0xff00)>>8 |(( (uint16)(A)&0x00ff)<<8))
#define htons(A) ((((uint32)(A)&0xff000000)>>24 | (((uint32)(A)&0x00ff0000)>>8 )| (((uint32)(A) & 0x0000ff00)<<8) | (((uint32)(A)&0x000000ff)<<24))
#define ntohs htons
#define ntohl htohl
#else
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #define,but not both,"
#endif
如何检查处理器是big-endian 还是little-endian?
由于联合体union的存放顺序是所有成员都是从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用的是LITTLE-ENDIAN模式还是BIG-ENDIAN模式读写
union
{
unsigned int a ;
unsigned char b;
}c;
int checkCPUendian()
{
c.a = 1; // 联合体中a现在起作用,联合体任意时刻只有一个变量起作用,各个成员变量共用一个内存空间 (1存放在低地址)
return (c.b == 1); // return (c.b == 1) 联合体中b现在起作用
} // return 1 : little-endian, 说明1存放在低地址
// return 0 :big-endian; 说明1存放在高地址
参考文章:http://blog.csdn.net/yasaken/article/details/7243757
big-edian 和 littile-endian。
本文简要描述这两种存储机制的特点与区别。
为了叙述方便,下面先对本文中简要用到的两个疏于进行简单定义
1.MSB是Most Significant Bit/Byte 的首字母缩写,通常译为最重要位或者最重要的字节。它通常用来表明在一个bit序列或者一个字节序列中对整个序列影响最大的位或者字节
2.LSB是Least Significant Bit/Byte 的首字母缩写,通常译为最不重要的位或者最不重要的字节,它通常用来表明在一个bit序列或者一个字节序列中对整个序列影响最小的位或者字节
3.big-endian:计算机体系结构中的一种描述多字节存储顺序的术语,在这种机制中最重要的字节(MSB)存放在最低端的地址上。如下:
双字节数0x1234以big-endian的方式存在起始地址0x00000020中
+--------------------------+ | 0x34 |<-- 0x00000021
+--------------------------+ | 0x12 |<-- 0x00000020
在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0X8B8A为例)
Big-Endian的bit序列编码方式
bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +------------------------------------------------+
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 | +-------------------------------------------------+
^ 0x8B 0x8A ^
MSB
LSB
注一:通常在TCP/IP协议中所说的网络序列(Network Order)就是使用Big-Endian规则。在TCP/IP网络通信中,通信双方把消息按照上面图方式编码,然后按照从MSB(bit0)到LSB(bit15)的顺序在网络上传输。
4.little-endian:计算机体系结构中一种描述多字节存储的术语,在这种机制中最不重要的字节(LSB)存放在最低端的地址上,通常用来描述一个字节中各个比特的排放次序。
双字节数0x1234以little-endian的方式存在起始地址0x00000020中
| 0x12 |<-- 0x00000021 +---------------------------+
| 0x34 |<-- 0x00000020 +---------------------------+
在Little-Endian中,对于bit序列中的序号编排和Big-Endian刚好相反,其方式如下(以双字节数0x8B8A为例):
Little-Endian的bit序列编码方式
bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----------------------------------------+
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 | +-----------------------------------------+
^ 0x8B 0x8A ^
MSB LSB
通常我们说的主机序(Host Order)就是使用Litlle - Endian规则。所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序(Little-Endian)到网络序(Big-Endian)的转换。
什么是字节序?
字节序:顾名思义,就是多个字节类型的数据在内存中存放的顺序,在跨平台已经网络程序中字节序才是一个应该考虑的问题。
字节序的两种分类:a: Little-Endian 就是低位字节排放在内存的低地址端,高字节排放在内存的高地址端。
b.Big-Endian就是高位字节排放在内存的低地址端,低位字节拍排放在内存的高地址端。
c.网络TCP/I各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称为网络字节序。
什么是高/低地址 什么是高/低字节
C程序映像中内存空间的分布情况,在《C专家编程》中或者《UNIX环境高级编程》中有关内存的分布情况大致如下:
--------------最高内存地址 0xffffffff -------------
栈底(高地址)
栈…
栈顶(低地址)
-------------------------------------------------------
NULL (空洞)
--------------------------------------------------------
堆
------------------------------------------------------
未初始化的数据
--------------------------------------(统称数据段)
初始化的数据
-------------------------------------------------------
正文段(代码段)
---------------最低内存地址 0x00000000--------
以上图为例如果我们在栈上分配一个unsigned char buf[4],那么这个数组变量在栈上是如何布局的呢?看下图:
------栈底(高地址)-----
buf[3]
buf[2]
buf[1]
buf[0]
----栈顶(低地址)------
高低字节: 拿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-Edian。那么在跨平台或网络程序中如何实现字节序的转换?这个通过C语言的移位操作很容易实现,例如:
#if define(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
#define htons(A) (A)
#define htonl(A) (A)
#define ntohs(A) (A)
#define ntohl(A) (A)
#elseif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define htons(A) (((uint16)(A)&0xff00)>>8 |(( (uint16)(A)&0x00ff)<<8))
#define htons(A) ((((uint32)(A)&0xff000000)>>24 | (((uint32)(A)&0x00ff0000)>>8 )| (((uint32)(A) & 0x0000ff00)<<8) | (((uint32)(A)&0x000000ff)<<24))
#define ntohs htons
#define ntohl htohl
#else
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #define,but not both,"
#endif
如何检查处理器是big-endian 还是little-endian?
由于联合体union的存放顺序是所有成员都是从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用的是LITTLE-ENDIAN模式还是BIG-ENDIAN模式读写
union
{
unsigned int a ;
unsigned char b;
}c;
int checkCPUendian()
{
c.a = 1; // 联合体中a现在起作用,联合体任意时刻只有一个变量起作用,各个成员变量共用一个内存空间 (1存放在低地址)
return (c.b == 1); // return (c.b == 1) 联合体中b现在起作用
} // return 1 : little-endian, 说明1存放在低地址
// return 0 :big-endian; 说明1存放在高地址
参考文章:http://blog.csdn.net/yasaken/article/details/7243757
相关文章推荐
- 计算机存储体系结构
- 存储相关的基于Intel体系的计算机体系结构演进
- 浅谈大数据背景下的计算机体系结构存储层次结构研究
- 【计算机体系结构】存储-理解RAID条带话的概念
- 【转帖】计算机体系结构——存储体系
- 【计算机系统结构】 存储体系
- 【计算机体系结构】存储--远程镜像技术
- 计算机体系结构——存储体系
- 中国计算机学会CCF推荐国际学术会议和期刊目录-计算机体系结构/并行与分布计算/存储系统
- 【计算机体系结构】存储--快照技术
- 中国计算机学会CCF推荐国际学术会议和期刊目录-计算机体系结构/并行与分布计算/存储系统
- 浅谈大数据背景下的计算机体系结构存储层次结构研究
- 计算机系统结构 存储体系
- 中国计算机学会CCF推荐国际学术会议和期刊目录-计算机体系结构/并行与分布计算/存储系统
- 浅谈大数据背景下的计算机体系结构存储层次结构研究
- 【计算机体系结构】存储--NAS+SAN
- 浅谈大数据背景下的计算机体系结构存储层次结构研究-(百度移动端笔试题之一)
- MySQL技术内幕读书笔记(一)——Mysql体系结构和存储引擎
- 2012年1月10日 星期二(oracle读书笔记,体系架构和存储结构)
- 计算机网络体系结构