寻址和字节顺序 —所谓的大小端
某些机器在存储器中按照从最低有效字节到最高有效字节的顺序存储对象,这种方式称之为小端法;而有些机器按照从最高有效字节到最低有效字节进行存储,这种方式称之为大端法。
实例,一个int型的数据0x12345678,占四个字节,假设地址为0x2000 ~ 0x2003。
地址 | 0x2000 | 0x2001 | 0x2002 | 0x2003 |
---|---|---|---|---|
小端法 | 0x78 | 0x56 | 0x34 | 0x12 |
大端法 | 0x12 | 0x34 | 0x56 | 0x78 |
C程序大小端判定
大小端的判断方法很多,不过我觉得联合体union可以简单明了的解释这个问题,定义的union多个成员共用一块内存,每一个成员在任一时刻有且只有一个成员使用此块内存。下例中的word和byte就占用同一内存,因此对成员word赋值,成员byte里面就存放了相应的值。
对word赋值0x12345678,假设地址为0x2000 ~ 0x2003;大小端存放方式见下表。
成员的地址 | 0x2000 | 0x2001 | 0x2002 | 0x2003 |
---|---|---|---|---|
小端法/byte[0~3] | 0x78 | 0x56 | 0x34 | 0x12 |
大端法/byte[0~3] | 0x12 | 0x34 | 0x56 | 0x78 |
#include "stdio.h"
#define uint8 unsigned char
#define uint16 unsigned short
#define uint32 unsigned int
typedef union
{
uint32 word;
uint8 byte[4];
}Data;
int main(void)
{
int i = 0;
Data num;
num.word = 0x12345678;
printf("0x12345678的存放方式:\n");
printf("addr:");
for(i = 0; i < sizeof(Data); i++)
{
printf("%p ", &num.byte[i]);
}
if(num.byte[0] == 0x12)
printf("\n大端法:");
if(num.byte[0] == 0x78)
printf("\n小端法:");
for(i = 0; i < sizeof(Data); i++)
{
printf("0x%-12x ", num.byte[i]);
}
printf("\n");
return 0;
}
C程序执行结果
得出此机器是以小端模式存放数据的
lirong@PC-LR:~/code/test$ ./main
0x12345678的存放方式:
addr:0x7fff4f8292c0 0x7fff4f8292c1 0x7fff4f8292c2 0x7fff4f8292c3
小端法:0x78 0x56 0x34 0x12
2018-11-14-LR