什么是大小端模式
大小端存储由
CPU架构 决定。
大端模式(
big endian
):低地址存在高位,高地址存在低位;
小端模式(
Little Endian
):低地址存在低位;高地址高位;
例如:
使用大端模式的有:Mac OS、PowerPC、IBM、Sun、
TCP/IP网络数据流;
使用小端模式的有:x86、Linux;
而ARM可以是大端模式,也可以是小端模式;
如何判断CPU是大端模式还是小端模式
// liunx内核的方法
void check_CPU_mode_1()
{ // union共享同一段内存;
// 对齐方式需适合其中所有的成员,即大小能被其包含的所有基本数据类型的大小所整除。
static union{
char c[4];
unsigned long mylong; // unsigned long 为4个字节
}endian_test = { {'L','?','?','B'} };
#define ENDIANNESS ( (char)endian_test.mylong )
if ( 'b' == ENDIANNESS )
printf(" it's Big endian\n");
else
printf("it's Little endian\n");
}
// 指针方法
void check_CPU_mode_2()
{
int a = 1;
unsigned char *p = (unsigned char*)(&a); // p指向指向a地址最低一个字节
if( *p == 1)
cout << "CPU使用小端模式存储\n";
else
cout << "CPU使用大端模式存储\n";
}
用宏实现大小端转换
/* 定义多行宏时在每一行后面加 '\' */
//对于16位数据
#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8)| \
(( (uint16)(A) & 0x00ff) << 8))
//对于32位数据
#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000) >> 24) | \
(( (uint32)(A) & 0x00ff0000) >> 8) | \
(( (uint32)(A) & 0x0000ff00) << 8) | \
(( (uint32)(A) & 0x000000ff) << 24))
数组在大小端情况下的存储情况
若存在unsigned int value = 0x12345678,用unsigned char buf[4]来表示value,则
例题1
假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?
#include <stdio.h>
int main()
{
long long a = 1, b = 2, c = 3;// long long 4字节 = 32bit
printf("%d,%d,%d\n", a, b, c); // %d格式输出的是4个字节大小,
return 0;
}
输出结果为:1,0,2
小端模式,a端为低地址,c端为高地址,long long 为8字节,a=0x01,b=0x02,c=0x03
注:printf()是一个库函数,C,C++中函数的参数是从右往左入堆栈的,再弹出;%d格式输出的是4个字节大小,
|
小端模式
| |
0x03
|
c
|
0
|
3
| ||
0x02
|
b
|
0
|
2
| ||
0x00
|
a
|
0
|
1
|
若存在数据 A = 305419896,十六进制表示为:0x12345678
|
大端模式
| |
内存地址
|
|
HEX数位
|
0x03
|
|
78
|
0x02
|
56
| |
0x01
|
|
34
|
0x00
|
12
|
一个字节地址空间占8个位(bit),而一个十六进制数据位占4位(bit),
所以一个内存地址可以存两个十六进制数据位
例题2
int main()
{
unsigned int value = 1024; // 4 个 字节
cout << hex << &value << endl;
bool *p = (bool*)(&value);
cout << hex << p << endl;
p++;// p 指向 value地址, 不过移动的话按 bool 步长移动
cout << p << endl;
bool condition = *((bool *)(&value)); //(bool *)(&value);取的是第一位的地址
if (condition)
printf("condition=1");
else
printf("condition=0");
}
unsigned int 为4个字节, 1024 = 0x0000 0400
注: 涉及地址间的强制类型转换;16进制分析;大小端模式分析;
小端模式
| 大端模式 | ||
高地址
|
00
|
|
00
|
|
00
|
|
04
|
|
04
|
|
00
|
低地址 |
00
|
|
00
|