1. 程式人生 > 實用技巧 >大端和小端

大端和小端

【定義】

大端和小端(Big Ending & Little Ending),對於int、long等資料型別,BE指從低地址到高地址依次存放資料的高位元組到低位元組,LE相反,指從低地址到高地址依次存放資料的低位元組到高位元組。

【舉例】

如果我們將0x1234abcd 寫入到以 0x0000 開始的記憶體中,則Little endian 和 Big endian 模式的存放結果如下:
地址 0x0000 0x00010x0002 0x0003
big-endian0x12 0x34 0xab 0xcd
little-endian 0xcd 0xab 0x34 0x12

一般來說,x86 系列 CPU 都是 little-endian 的位元組序,PowerPC 通常是 big-endian,網路位元組順序也是 big-endian,還有的CPU 能通過跳線來設定 CPU 工作於 Little endian 還是 Big endian 模式。

【轉換】

htonl() htons() 從主機位元組順序轉換成網路位元組順序
ntohl() ntohs() 從網路位元組順序轉換為主機位元組順序

Big-Endian轉換成Little-Endian

#define BigtoLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))
#define BigtoLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | (((uint32)(A) & 0x00ff0000) >> 8) | \
             (((uint32)(A) & 0x0000ff00) << 8) | (((uint32)(A) & 0x000000ff) << 24))

【大小端檢測方法】

聯合體union的存放順序是所有成員都從低地址開始存放,利用該特性就可以輕鬆地獲得了CPU對記憶體採用Little-endian還是Big-endian模式讀寫。Linux 的核心作者們僅僅用一個union 變數和一個簡單的巨集定義就實現了(ENDIANNESS=’l’表示系統為little endian,為’b’表示big endian):

static union { char c[4]; unsigned long mylong; } endian_test = {{ 'l', '?', '?', 'b' } };

#define ENDIANNESS ((char)endian_test.mylong)