Little-Endian是说低位字节在前,Big-Endian反之,所以翻成大尾小尾有歧义;只说大头小头也有点含糊。
还不如就叫“低位字节开头”和“高位字节开头”。
1 关于Endian这个词语
[quote] “endian”这个词出自Jonathan Swift 的《格列佛游记》。其中交战的两个派别无法就应该从哪一端--小端(Little-Endian)还是大端(Big-Endian)打开一个半熟的鸡蛋达成一致。由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。在那个时代,Swift是在讽刺英国和法国之间的持续冲突,Danny Cohen,一位网络协议的早期开创者,第一次使用这两个术语来指代字节顺序,后来这个术语被广泛接纳了 [/quote]
摘自《深入理解计算机系统》
我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
2 基本概念
[1]在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分。比如一个16进制数字0x12345678, 在内存存放的方式如下(Assume Base Address is 0x100):
值 |
0111,1000(0x78) |
0101,0110(0x56) |
0011,0100(0x34) |
0001,0010(0x12) |
地址(0x) |
100 |
101 |
102 |
103 |
Intel 的处理器(我们普通的PC机)就是采用“little-endian”字节顺序
另一种称为big-endian,正好相反,存放在内存中最低位的数值是来自数据的最左边部分。比如一个16进制数字0x12345678, 在内存存放的方式如下:
值 |
0001,0010(0x78) |
0011,0100(0x56) |
0101,0110(0x34) |
0111,1000(0x12) |
地址(0x) |
100 |
101 |
102 |
103 |
Motorala的处理器(MAC机)采用“big-endian”字节顺序
3 哪种方法更好[2]?
你可能看见过很多关于这两种形式的相对优点的讨论,最激烈的争论是关于PC和MAC的相对优点。这两种形式都有其优点和缺点。
在“little-endian”形式中,提取一个,两个,四个或者更长字节数据的汇编指令以与其他所有格式相同的方式进行:首先在偏移地址为0的地方提取最低位的字节,因为地址偏移和字节数是一对一的关系,多重精度的数学函数就相对地容易写了。
在“big-endian”的形式中,靠首先提取高位字节,你总是可以由看看在偏移位置为0的字节来确定这个数字是正数还是负数。你不必知道这个数值有多长,或者你也不必跳过一些字节来看这个数值是否含有符号位。这个数值是以它们被打印出来的顺序存放的,所以从二进制到十进制的函数特别有效。
4 C代码(它们之间的转换和判断)
/** \fn is_little_endian(void)
* \brief 判断是否是"little_endian"字节序
* \param
* \return 1:little_endian 0:big_endian
*/
char is_little_endian(void)
{
int bit = 1;
char *p = (char *)&bit;
return *p;
}
/** \fn reverse_big_little_endian(int N)
* \brief "big_endian"和"little_endian"的相互转换
* \param int N:要转换的数据
* \return 返回转换的结果
*/
int reverse_big_little_endian(int N)
{
int reverse;
char bit0, bit1, bit2, bit3;
bit0 = (N & 0x000000ff);
bit1 = (N & 0x0000ff00) >> 8;
bit2 = (N & 0x00ff0000) >> 16;
bit3 = (N & 0xff000000) >> 24;
reverse = (bit0 << 24) | (bit1 << 16) | (bit2 << 8) | (bit3);
return reverse;
}