转自:http://blog.csdn.net/njnu_mjn/article/details/9141231
概念
字节顺序是指多字节的值在硬件中的存储顺序. 一般分为大端(big-endian)和小端(little-endian).
大端: 先存储高字节(Most significant bit), 或者说, 高字节存储在低地址, 低字节存储在高地址.
小端: 先存储低字节(Least significant bit), 或者说, 低字节存储在低地址, 高字节存储在高地址.
以4字节的数字0x01020304为例, 起始地址为n, 请见下表:
大端 |
| ||||||||||
小端 |
|
大端或者小端是由CPU决定的, 请见下表:
大端 | 小端 | 其中之一 |
AVR32 FR-V H8300 PA-RISC S390 Motorola 680x0 SPARC | Alpha CRIS Blackfin Intel 64 IA-32 (x86) MN10300 | ARM SuperH (sh) M32R MIPS Xtensa PowerPC |
对于PowerPC, 可以被配置使用大端还是小端, Linux选择大端.
大端或者小端的存储方式, 对于写应用软件的程序员来讲, 是透明的, 无需关心. 而当两台存储方式不同的机器之间传输多字节的值时, 就要用同一种存储方式. 对于TCP/IP协议, 使用大端方式.(不是所有的通讯协议, 都使用大端, 例如呢? fix me!)
位操作与字节顺序有关吗?
位操作像加减乘除一样, 跟数据的存储方式是没有关系的. 请见以下的测试代码及输出.
这个是将所有的字节顺序完全颠倒的一个宏,调用BSWAP_64(x) 即可将x的Byte顺序完全颠倒,实现非常简洁,足见实现者的功力。
#define BSWAP_8(x) ((x) & 0xff)
#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
下面的这个方法神了,因为他并不需要定义一个变量就可以实现交换两个数。
#define swap(a, b) \
(((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
上面的这个完全就是利用了RAID中的xor思想啊,神奇啊。而且减少了变量的申请和释放。
多看看内核代码,多学习一下内核中的宏的使用,还是挺提高编程能力的。