1. 大小端的区别
little endian:把低位字节存放在内存的低位; //
big endian: 将低位字节存放在内存的高位;
比如:0x1234,则12 就属于高位字节;34 属于低位字节
假如从地址0x0000 0000开始的一个字节中保存数据0x12345678, 这2中字节序在内存当中存放顺序为:
address: 0x0000 0000 0x0000 0001 0x0000 0002 0x0000 0003
big_endian 0x12 0x34 0x56 0x78
lit-endian 0x78 0x56 0x34 0x12
2. 为什么会有大小端模式的区分呢?
因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
当前的存储器,多以byte为访问的最小单元,当一个逻辑上的整理必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是endian的问题应运而生了,对于不同的存储方法,就有Big-endian和Little-endian两个描述.
(这两个术语来自于 Jonathan Swift 的《格利佛游记》其中交战的两个派别无法就应该从哪一端--小端还是大端--打开一个半熟的鸡蛋达成一致。在那个时代,Swift是在讽刺英国和法国之间的持续冲突,Danny Cohen,一位网络协议的早期开创者,第一次使用这两个术语来指代字节顺序,后来这个术语被广泛接纳了。)
3. 各种CPU支持的字节序不同
lit-endian: x86
big_endian: Motorola/IBM/SUM cpu
ARM 既能工作于大端也能工作于小端
所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。
4. 怎么检测当前的处理器属于哪个字节序?
a. 用VC2005 调试查看short变量在内存中的布局,如下:
int _tmain(int argc, _TCHAR* argv[])
{
short t = 0x1234;
return 0;
}
&t = 0x12ff60, t 在内存当中的布局如下图:
由此可见, x86 CPU 采用的是little endian.
b. 利用字节序的基本规则进行判断
enum BYTE_ENDIAN
{
little_endian,
big_endian,
unknown_error
};
BYTE_ENDIAN check_byte_endian_1()
{
short t = 0x1234;
char c = (*(char *)(&t));
if (0x12 == c)
{
return big_endian;
}
else if(0x34 == c)
{
return little_endian;
}
return unknown_error;
}
3.
/*---------------------------------------------------------------------------
联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性,
轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写
-----------------------------------------------------------------------------*/
BYTE_ENDIAN check_byte_endian_2()
{
union test_endian
{
char c;
short s;
};
test_endian t;
t.s = 0x1234;
if (0x12 == t.c)
{
return big_endian;
}
else if(0x34 == t.c)
{
return little_endian;
}
return unknown_error;
}
==================================
另外,可以参考百度百科(关键字:字节序):http://baike.baidu.com/view/2194385.htm 获取更多信息。