大尾端(big endian)和小尾端(little endian)的问题类似于写字时是从右往左写还是从左往右写的问题。说起来不难,但是在计算机世界中,我们必须要规定采用哪种形式,而并无优劣之分,所以演变到现在,就既有大尾又有小尾.X86就是小尾的,龙芯也用的小尾,早期的MIPS使用的是大尾端,这决定了访存的方向问题。
精确的讲,大尾端和小尾端的区别是系统里整数是从右往左表示还是从左往右表示。表示的不同就意味着重要性不同的位位置不同,大尾端从左往右表示,那么权重大的字节在左边即在低地址处,而小尾端相反。不管时处理器,虚拟机还是网路协议都需要规定大小尾端问题。
如图是X86的存储形式,若大小尾端混用,则会一团糟。
![]()
对于网络协议,大小尾端必须统一,我们的TCP/IP使用大尾端,也就是说所有电脑的网络端口都要是大尾端,对于电脑CPU是大尾端的,无须太多处理;但若是小尾端的机器,则需要在接受报文时做转换,幸好已经有比较高效的宏来实现,使得这种转换无须太多代价。宏定义如下,实现字节重拍序.
#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
#define htons(A) (A)
#define htonl(A) (A)
#define ntohs(A) (A)
#define ntohl(A) (A)
#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
(((uint16_t)(A) & 0x00ff) << 8))
#define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \
(((uint32_t)(A) & 0x00ff0000) >> 8) | \
(((uint32_t)(A) & 0x0000ff00) << 8) | \
(((uint32_t)(A) & 0x000000ff) << 24))
#define ntohs htons
#define ntohl htonl
#else
#error "Must define one of BIG_ENDIAN or LITTLE_ENDIAN"
#endif
参考
http://www.netrino.com/Embedded-Systems/How-To/Big-Endian-Little-Endian

Google reader好久不见你更新~
@Figo, 最近比较忙,更新就少了很多:)
囧
#define htons(A) ((((uint16_t)(A) & 0xff00) >>
@zsc, 太智能的网站让人很无奈。。。。