大端和小端
【定义】
大端和小端(Big Ending & Little Ending),对于int、long等数据类型,BE指从低地址到高地址依次存放数据的高字节到低字节,LE相反,指从低地址到高地址依次存放数据的低字节到高字节。
【举例】
如果我们将0x1234abcd 写入到以 0x0000 开始的内存中,则Little endian 和 Big endian 模式的存放结果如下:
地址 0x0000 0x0001 0x0002 0x0003
big-endian 0x12 0x34 0xab 0xcd
little-endian 0xcd 0xab 0x34 0x12
一般来说,x86 系列 CPU 都是 little-endian 的字节序,PowerPC 通常是 big-endian,网络字节顺序也是 big-endian,还有的CPU 能通过跳线来设置 CPU 工作于 Little endian 还是 Big endian 模式。
【转换】
htonl() htons() 从主机字节顺序转换成网络字节顺序
ntohl() ntohs() 从网络字节顺序转换为主机字节顺序
Big-Endian转换成Little-Endian
#define BigtoLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))
#define BigtoLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | (((uint32)(A) & 0x00ff0000) >> 8) | \
(((uint32)(A) & 0x0000ff00) << 8) | (((uint32)(A) & 0x000000ff) << 24))
【大小端检测方法】
联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。Linux 的内核作者们仅仅用一个union 变量和一个简单的宏定义就实现了(ENDIANNESS=’l’表示系统为little endian,为’b’表示big endian):
static union { char c[4]; unsigned long mylong; } endian_test = {{ 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.mylong)
浙公网安备 33010602011771号