`
ld_hust
  • 浏览: 170307 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

字节序

阅读更多

这几天又开始做网络方面的应用了,既然是网络编程,字节序肯定是需要牢记的一个知识点了。贴篇文章,以备忘!

不同的 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-endian   little-endian
0x0000   0x12       0xcd
0x0001   0x23       0xab
0x0002   0xab       0x34
0x0003   0xcd       0x12
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-PA     NT     Little endian
HP-PA     UNIX     Big endian
Intelx86    
 全部      Little endian <-----x86 系统是小端字节序系统 

Motorola680x()     
全部      Big endian
MIPS     NT     Little endian
MIPS     UNIX     Big endian
PowerPC     NT     Little endian
PowerPC    
  NT     Big endian   <-----PPC 系统是大端字节序系统 

RS/6000     UNIX     Big endian
SPARC     UNIX     Big endian
IXP1200 ARM
 
核心      全部      Little endian

2.

一、字节序定义

字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。

其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。

在所有的介绍字节序的文章中都会提到字节序分为两类: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。按照大端方式存放在内存中。

二、高/低地址与高低字节

首先我们要知道我们C程序映像中内存的空间布局情况:在《C专家编程》中或者《Unix环境高级编程》中有关于内存空间布局情况的说明,大致如下图:
----------------------- 最高内存地址 0xffffffff
| 栈底
.
.              栈
.
栈顶
-----------------------
|
|
\|/

NULL (空洞)

/|\
|
|
-----------------------
                堆
-----------------------
未初始化的数据
----------------(统称数据段)
初始化的数据
-----------------------
正文段(代码段)
----------------------- 最低内存地址 0x00000000

以上图为例如果我们在栈上分配一个unsigned char buf[4],那么这个数组变量在栈上是如何布局的呢[注1]?看下图:
栈底 (高地址)
----------
buf[3]
buf[2]
buf[1]
buf[0]
----------
栈顶 (低地址)

现 在我们弄清了高低地址,接着来弄清高/低字节,如果我们有一个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

分享到:
评论

相关推荐

    浅学字节序——字节序大小端,主机字节序,网络字节序的理解

    ### 字节序的基础概念 字节序,又称为字节顺序或字节排列方式,指的是在计算机内存中或网络传输过程中多字节数据的存储顺序。简单来说,它定义了多字节数据中各个字节如何按顺序排列。在实际编程工作中,尽管很多...

    IP、主机字节序、网络字节序、互转

    IP、主机字节序、网络字节序、互转 ------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using ...

    网络字节序和主机字节序

    网络字节序和主机字节序 在计算机科学中,字节序(Endianness)是指整数在内存中保存的顺序。不同的 CPU 有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。 常见的有两种字节序:...

    本地字节序和网络字节序.pdf

    《本地字节序和网络字节序:理解与应用》 在计算机科学中,字节序(Byte Order)指的是多字节数据类型在内存中存储时,其各个组成字节的排列顺序。这一概念对于理解数据在网络传输以及跨平台编程中至关重要。本文将...

    字节序与位序

    "字节序与位序详解" 字节序(Byte Order)和位序(Bit Order)是计算机系统中两个重要的概念,它们决定了计算机系统如何存储和处理多字节整数。在本文中,我们将详细介绍字节序和位序的定义、类型、特点以及在...

    利用宏将网络字节序和主机字节序ip格式化输出方法

    利用宏将网络字节序和主机字节序ip格式化输出为字符串ip

    大小端字节序介绍几转换

    ### 大小端字节序概念与转换 #### 一、引言 在计算机系统中,数据的存储和传输方式至关重要。特别是在网络通信领域,不同的系统可能会采用不同的字节序来存储多字节数据,这可能导致数据解释上的不一致。因此,理解...

    络字节序、地址转换源代码

    字节序分为两种类型:大端字节序(Big-Endian)和小端字节序(Little-Endian)。理解这两种字节序对于进行跨平台的网络通信至关重要,因为不同的处理器架构可能使用不同的字节序。例如,PowerPC和SPARC通常使用大端...

    float字节序高低位转换.txt

    float字节序高低位转换.txt

    64位数字节序转换

    项目中需要64位数的字节序转换,主机序转换成网路序或者相反转换,写了2个函数,有需要的可以参考。

    高字节序,低字节序讲解

    高字节序,低字节序讲解。高字节序,低字节序讲解。高字节序,低字节序讲解

    判断主机字节序的C代码

    用C语言写的判断主机字节序的代码,一共有2种方法判断

    5_网络字节序_werevj4_

    在跨平台的网络编程中,字节序转换函数如htonl(主机到网络字节序,long)、ntohl(网络到主机字节序,long)、htons(主机到网络字节序,short)和ntohs(网络到主机字节序,short)非常常见,它们确保数据在网络上...

    网络字节序与主机字节序

    网络字节序与主机字节序

    判断主机字节序大小端

    判断主机到底是大端还是小端的c程序!利用位置判断

    JAVA网络字节序转换1

    Java 网络字节序转换是编程过程中一个重要的概念,尤其在跨平台通信和处理二进制数据时。字节序是指多字节数据(如整数或浮点数)在内存或文件中存储的顺序。主要有两种字节序:Big-Endian(大端字节序)和 Little-...

    进制转换-编码的设计原理-位运算-内存与内存地址-字节序-java解码编码字节流

    二进制杂谈 1、十进制、二进制、十六进制 2、计算机储存单位 3、进制转换 4、有符号编码 5、反码的设计原理 6、二进制的位运算 7、位操作符 8、内存与内存地址 9、字节序 10、Java解码 11、Java编码

    网络字节序_werevj4_源码.rar

    网络字节序是计算机网络通信中的一个重要概念,它涉及到数据在网络中的传输方式。在不同的计算机系统中,数据存储的顺序可能会有所不同,这被称为字节序。主要有两种字节序:大端字节序(Big-Endian)和小端字节序...

    网络字节序 主机字节序.txt

    网络字节序 主机字节序

    字节序、MSB、LSB.docx

    在计算机科学中,字节序是一个至关重要的概念,特别是在跨平台通信和网络编程中。字节序,又称端序或尾序,定义了多字节数据如何在内存中存储和在网络上传输。Endianness这一术语源于乔纳森·斯威夫特的《格列佛游记...

Global site tag (gtag.js) - Google Analytics