big_endian和little_endian的说明
来源:互联网 发布:ubuntu admin组不存在 编辑:程序博客网 时间:2024/05/21 02:20
big_endian 、little_endian 用于自动改变二进制位存放顺序
Big Endian and Little Endian
谈到字节序的问题,必然牵涉到两大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中的存储顺序如下所示:
Big Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 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方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C中提供了下面四个转换字节序的宏。
Big Endian and Little Endian
谈到字节序的问题,必然牵涉到两大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中的存储顺序如下所示:
Big Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 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方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C中提供了下面四个转换字节序的宏。
Endian的转换则只要交换高低位的字节就行了,用与运算的效率较高,以32为数据为例:
inline void ConvertEndian32( LPVOID lpMem )
{
BYTE * p = (BYTE*)lpMem;
p[0] = p[0] ^ p[3];
p[3] = p[0] ^ p[3];
p[0] = p[0] ^ p[3];
p[1] = p[1] ^ p[2];
p[2] = p[1] ^ p[2];
p[1] = p[1] ^ p[2];
}
^ 真的很神奇,a^b=c , c^b=a^b^b=a , a^c=a^a^b=b
看一个题目
请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
int checkCPU()
{
{
union w
{
int a;
char b;
} c;
c.a = 1;
return (c.b == 1);
}
}
- big_endian和little_endian的说明
- big_endian和little_endian的说明
- big_endian和little_endian的说明收藏[转]
- big_endian和little_endian的说明(转载)
- big_endian和little_endian的说明(转载)
- Big_Endian和Little_Endian
- big_endian和little_endian(转)
- Endian.BIG_ENDIAN 和Endian.LITTLE_ENDIAN
- Big_endian Little_endian
- 设置ByteOrder的顺序LITTLE_ENDIAN,BIG_ENDIAN
- cpu 的大端,小端,Big_endian,little_endian
- 大端(Big_endian)和小端(Little_endian)
- C函数,判断处理器是Big_endian的还是Little_endian的
- 编译原理: Big_endian, Little_endian 问题
- 若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
- 测试主机序号的例子(大端序、小端序、big_endian、little_endian)
- 关于测试PC是big_endian/little_endian
- 一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
- PHP树形菜单一次展开一个子项目
- 成功的人看到问题的时候是想到怎么解决问题
- Java学习手记--运算符和字符串的操作
- Java的char
- 无法加载2003项目,出现的错误
- big_endian和little_endian的说明
- 基于2D多边形的碰撞检测和响应(三)
- 新手Unix和Linux下C语言学习指南
- HTML 原始码 显示结果 描述
- fpdf 生成PDF 有关乱码的问题
- Oracle安装,登录EM后,显示数据库状态当前不可用
- windows电源管理的相关知识收集
- 在使automake autoconf 等工具管理的现有项目里增加自己源文件和静态库
- ssh 启动问题