(From《Computer Systems,A Programer's Perspective》)在几乎所有的机器上,多字节对象被存储为连续的字节序列,对象的地址为所使用字节序列中最低字节地址。某些机器选择在存储器中按照从最低有效字节到最高有效字节的顺序存储对象,这种最低有效字节在最前面的表示方式被称为小端法(little endian)(e.g.:Intel处理器上运行Linux,NT);某些机器则按照从最高有效字节到最低有效字节的顺序储存,这种最高有效字节在最前面的方式被称为大端法(big endian)(e.g.:Sun Microsystem UltraSPARC运行Solaris)。一般情况下,我们不必考虑字节顺序,但在下列三种情况下,字节顺序变得非常重要:
1. 在不同类型的机器之间通过网络传送二进制数据时。一个常见的问题是当小端法机器产生的数据被发送到大端法机器或者反之时,接受程序会发现,字(word)里的字节(byte)成了反序的。为了避免这类问题,网络应用程序的代码编写必须遵守已建立的关于字节顺序的规则,以确保发送方机器将它的内部表示转换成网络标准,而接受方机器则将网络标准转换为它的内部标准。
2. 当阅读表示整数的字节序列时。这通常发生在检查机器级程序时,e.g.:反汇编得到的一条指令:
80483bd: 01 05 64 94 04 08 add %eax, 0x8049464
3. 当编写规避正常的类型系统的程序时。(e.g.:下面的几个代码示例。)
判断当前机器环境是大端法还是小端法:
int i=1;
unsigned char * pointer = &i;
if(*pointer)//或pointer[0]
printf("Little Endian");
else printf("Big Endian");
unsigned char * pointer = &i;
if(*pointer)//或pointer[0]
printf("Little Endian");
else printf("Big Endian");
打印程序对象的字节表示:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len)
{
int i;
for(i=0;i<len;i++)
printf(" %.2x ", start[i]);
printf(" ");
}
void show_int(int x)
{
show_bytes((byte_pointer)&x, sizeof(int));//使用sizeof而不是使用魔数4
}
void show_unsignedInt(unsigned int x)
{
show_bytes((byte_pointer)&x,sizeof(unsigned int));
}
void show_short(short x)
{
show_bytes((byte_pointer)&x,sizeof(short));
}
void show_unsignedShort(unsigned short x)
{
show_bytes((byte_pointer)&x,sizeof(unsigned short));
}
void show_float(float x)
{
show_bytes((byte_pointer)&x, sizeof(float));
}
void show_pointer(void *x)
{
show_bytes((byte_pointer)&x, sizeof(void *));
}
int main(int argc, char *argv[])
{
int val=0x12345678;
byte_pointer valp=(byte_pointer)&val;
show_bytes(valp,1);
show_bytes(valp,2);
show_bytes(valp,3);
show_bytes(valp,4);
system("PAUSE");
return 0;
}
#include <stdlib.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len)
{
int i;
for(i=0;i<len;i++)
printf(" %.2x ", start[i]);
printf(" ");
}
void show_int(int x)
{
show_bytes((byte_pointer)&x, sizeof(int));//使用sizeof而不是使用魔数4
}
void show_unsignedInt(unsigned int x)
{
show_bytes((byte_pointer)&x,sizeof(unsigned int));
}
void show_short(short x)
{
show_bytes((byte_pointer)&x,sizeof(short));
}
void show_unsignedShort(unsigned short x)
{
show_bytes((byte_pointer)&x,sizeof(unsigned short));
}
void show_float(float x)
{
show_bytes((byte_pointer)&x, sizeof(float));
}
void show_pointer(void *x)
{
show_bytes((byte_pointer)&x, sizeof(void *));
}
int main(int argc, char *argv[])
{
int val=0x12345678;
byte_pointer valp=(byte_pointer)&val;
show_bytes(valp,1);
show_bytes(valp,2);
show_bytes(valp,3);
show_bytes(valp,4);
system("PAUSE");
return 0;
}