大端(Big Endian)与小端(Little Endian)详解
一、什么是Big Endian\Little Endian
只要一个对象超过一个字节,在内存中就有一个存放顺序。如数字:oXABCD。在系统中有两种存放方式。低内存地址存高位数,这种方式叫大端(Big Endian),低内存存放最低有效位,叫(Little Endian)。数字:oXABCD举例。
Big Endian。假设地址为0x0002
内存地址 | 存放值 |
0x0002 | A |
0x0003 | B |
0x0004 | C |
0x0005 | D |
Little Endian。假设地址为0x0002
内存地址 | 存放值 |
0x0002 | D |
0x0003 | C |
0x0004 | B |
0x0005 | A |
从存放顺序来看,Big Endian符合人们的认识习惯。Little Endian有点让人转不过弯来。
这个一般是CPU确定的。IBM 的PowerPC CPU、ARM、Hp的Alpha,从CPU类型来看基本上是RISC(Reduced Instruction Set Computing)精简指令CPU为Big Endian。Little endian的CPU 有Intel、AMD。这些CPU是CISC(Complex Instruction Set Computer).从操作系统看,Windows、Linux为Little ;Unix系列大部分为Big.
声明下:寄存器的数字都是按大端方式进行存放的
二、应用
1、数据库数据文件移植
如把oracle数据文件从Unix移植到Window平台,就要进行Big转Little.
2、Sock通信。跨平台的Sock通信,通信内容要注意Big与Little的相互转化
3、工控通信。如上位机与下位机数据交换
4、手机与PC通信程序。
三、通过程序判断是Little-endian还是Big-endian
源码如下:
/******************************************* 判断内存中字节存放顺序是big-endian 还是little-endian author:wsysoft@gmail.com ********************************************/ #include <stdio.h> #define ENDIAN 0 #define LITTLE -1 #define BIG 1
int getEndian(void){ /*__attribute__ ((aligned(4)))表示str字符数组的相地址是4的整数倍 是为了方便把字符数组的地址赋给整型指针变量,因为int型的大小为4,按内存分配方式,起指针变量的值(也就是地址)应该为4的整数倍,如果不用aligned属性加以指示指示,指针转换巩无效 */ unsigned char str[4] __attribute__ ((aligned(4)))={0x12,0x34}; int *p=(int *)str;//字符数组地址赋值给整型指错针变量,在str前不要加&
if (*p==0x1234) {return BIG;} else if (*p==0x3412) {return LITTLE;} else {return ENDIAN;} } int main(void){ int endian=getEndian(); switch(endian){ case ENDIAN: printf("Unknow endian Format\n"); break; case LITTLE: printf("Little-endian\n"); break; case BIG: printf("Big-endian\n"); break; default: printf("Unknow endian Format\n"); } return 1; } |
评论