大端(Big-endian)和小端(Little-endian)是两种存储数据的字节序.
大端: 数据的最高位存储在起始地址单元处, 低位存储在最高地址单元处.
小端: 数据的最低位存储在起始地址单元处, 高位存储在最高地址单元处,
比如:将十六进制数 0x01234567 存储在地址 0x100 处:
大端模式数据的高位(符号位)首先被机器取出, 便于快速判断正负.
小端模式数据按CPU读取顺序存储运算更高效.
大小端模式的判断: 取低地址一个字节的数据与数据的高8位或低8未比较.
bool is_big_endian()
{
int num = 0x12345678;
// 取出num的起始地址(指向4字节的int)
// 强制转换为指向单字节的指针
// 解引得到起始地址前8位所存储的值
char low_adress_value = *(char*)#
// 低地址处是高字节,则为大端
if ( low_adress_value == 0x12 ){
return true;
}
return false;
}
大小端模式的转换: 利用宏和位运算.
// 实现16bit的数据之间的大小端转换
// 分别取高8位右移, 低8位左移
#define BLSWITCH16(A) ( ( ( (uint16)(A) & 0xff00 ) >> 8 ) | \
( ( (uint16)(A) & 0x00ff ) << 8 ) )
// 实现32bit的数据之间的大小端转换
// 第一个高8位左移至第二个低8位, 第二个高8位左移至第一个低8位
// 第一个低8位左移至第二个高8位, 第二个低8位左移至第一个高8位
#define BLSWITCH32(A) ( ( ( (uint32)(A) & 0xff000000) >> 24) |\
(((uint32)(A) & 0x00ff0000) >> 8) | \
(((unit32)(A) & 0x0000ff00) << 8) | \
(((uint32)(A) & 0x000000ff) << 32) )
目前的使用情况是:
- Intel的80×86系列芯片使用小端存储模式
- ARM芯片默认采用小端,但可以切换为大端
- MIPS芯片采用大端,但可以在大小端之间切换
- 在网络上传输的数据普遍采用的都是大端