本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性。
参考资料:UNPV13e
字节序的概念是最基础不过的,但这东西学了不经常用就忘,所以以后学习回顾后都记成笔记以备查询使用,并且也可以记录我近段时间的学习历程。
内存中存储数据有两种方法:一种是低字节存在低地址,高字节存在高地址,称为小端字节序(little-endian);另一种正常好相反,低字节存在高地址处,高字节存在低地址处。只要记住小端字节序:小高高(小代表小端,第一个高代表高字节,第二个代码高地址),那么另外一个大端自然而然就知道。一般情况下,网络字节序使用大端,intel x86主机序为小端。本文先画个草图,然后给出两个判断当前主机是小端还是大端的源码,结合代码就能更好理解和记忆。
低地址 高地址
------------------------------------->
小端字节序 | 低字节| | | 高字节 |
------------------------------------->
图1
比如int a = 0x01020304,
如果是小端,在内存中的分布就如下图2:
低地址 高地址
------------------------------------->
小端字节序 | 0x04 | 0x03 | 0x02 | 0x01 |
------------------------------------->
图 2
如果是大端,在内存中的分布就如下图3:
低地址 高地址
------------------------------------->
大端字节序 | 0x01 | 0x02 | 0x03 | 0x04 |
------------------------------------->
图 3
代码一:
结合以上图2、图3,给出判断当前主机字节序的c源码:
//mybyteorder
#include
int main(void)
{
int a = 0x01020304;//0x04相当于低字节,0x01为高字节。
if(*(char *)&a == 0x01)//如果a的首地址(即低地址)第一个字节长度地址存放的是高字节内容0x01,那么主机序为大端。
printf("big.\n");
else if(*(char*)&a == 0x4)//如果a的首地址一个字节长度地址存放的是低字节内容04,那么主机序为小端。
printf("small.\n");
return 0;
}
[root@xxx study]# gcc mybyteorder.c -Wall -o app
[root@xxx study]# ./app
small.
代码二(来到UNPV1e3):
此代码片段还可以理解union这个数据类型的使用,unp.h在UNPV1e3源码中都有,包括此代码也有。
//byteorder.c
#include "unp.h"
int
main(int argc, char **argv)
{
union {
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;//0x02为低字节,0x01为高字节。
printf("%s: ", CPU_VENDOR_OS);
if (sizeof(short) == 2) {
if (un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
} else
printf("sizeof(short) = %d\n", sizeof(short));
exit(0);
}
[root@xxx intro]# make
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o byteorder.o byteorder.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -o byteorder byteorder.o ../libunp.a -lpthread
[root@xxx intro]# ./byteorder
i686-pc-linux-gnu: little-endian
正因为保留代码一,是想看其对于非char类型进行char操作的过程,当然其可改成像代码二一样使用union的方法:
int main(void)
union{
int a;
char s[sizeof(int)];
}u;
u.a = 0x01020304;
if(u.s[0] == 0x01)
printf("big.\n");
else if(u.s[0] == 0x04)
printf("small.\n");
return 0;
}
阅读(351) | 评论(0) | 转发(0) |