Endian
Endian
尋址
多字節(jié)對象被存儲為連續(xù)的字節(jié)序列,對象的地址為所使用字節(jié)中最小的地址。
例如,假設(shè)一個類型為 int 的變量 a 的地址為 0x100,也就是說,地址表達式 &a 的值為 0x100。那么,(假設(shè)數(shù)據(jù)類型 int 為32位表示) a 的 4 個字節(jié)將被存儲在內(nèi)存的 0x100、0x101、0x102 和 0x103 位置。
字節(jié)順序
最低有效字節(jié)存儲在起始地址,這稱為小端(Little Endian)字節(jié)序;最高有效字節(jié)存儲在起始地址,這稱為大端(Big Endian)字節(jié)序。
術(shù)語“小端”和“大端”表示多字節(jié)值的哪一端(小端或大端)存儲在該值的起始地址。
大多數(shù) Intel 兼容機都只用小端模式。另一方面,IBM 和 Oracle 的大多數(shù)機器則是按大端模式操作。
在下圖中,我們標明內(nèi)存地址增長的方向為從左到右。我們還標明最高有效位(Most Significant Bit,MSB)是這個32位值最左邊一位,最低有效位(Least Significant Bit,LSB)是這個32位值最右邊一位。 最高有效字節(jié)(Most Significant Byte)是 Byte3=0x01,最低有效字節(jié)(Least Significant Byte)是 Byte0=0x67 。
Endian Conversion Functions
我們把某個給定系統(tǒng)所用的字節(jié)序稱為主機字節(jié)序(host byte order),網(wǎng)絡(luò)協(xié)議為網(wǎng)絡(luò)字節(jié)序(network byte order)(大端字節(jié)序)。
網(wǎng)絡(luò)字節(jié)序是大端字節(jié)序。
Linux
下面4個函數(shù)是主機字節(jié)序和網(wǎng)絡(luò)字節(jié)序之間相互轉(zhuǎn)換的函數(shù)。在這些函數(shù)的名字中,h代表host,n代表network,s代表short,l代表long。short和long這兩個稱謂是出自4.2BSD的Digital VAX實現(xiàn)的歷史產(chǎn)物。如今我們應(yīng)該把s視為一個16位的值(例如TCP或UDP端口號),把l視為一個32位的值(例如IPv4地址)。事實上即使在64位的Digital Alpha中,盡管長整數(shù)占用64位,htonl和ntohl函數(shù)操作的仍然是32位的值。
當使用這些函數(shù)時,我們并不關(guān)心主機字節(jié)序和網(wǎng)絡(luò)字節(jié)序的真實值(或為大端,或為小端)。我們所要做的只是調(diào)用適當?shù)暮瘮?shù)在主機和網(wǎng)絡(luò)字節(jié)序之間轉(zhuǎn)換某個給定值。在那些與網(wǎng)際協(xié)議所用字節(jié)序(大端)相同的系統(tǒng)中,這四個函數(shù)通常被定義為空宏。
// converts host byte order and network byte order #include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);These functions convert the byte encoding of integer values from the byte order that the current CPU(the “host”) uses, to and from little-endian and big-endian byte order.
// These functions convert the byte encoding of integer values from the byte order that the current CPU (the "host") uses, // to and from little-endian and big-endian byte order. #include <endian.h> uint16_t htobe16(uint16_t host_16bits); uint16_t htole16(uint16_t host_16bits); uint16_t be16toh(uint16_t big_endian_16bits); uint16_t le16toh(uint16_t little_endian_16bits);uint32_t htobe32(uint32_t host_32bits); uint32_t htole32(uint32_t host_32bits); uint32_t be32toh(uint32_t big_endian_32bits); uint32_t le32toh(uint32_t little_endian_32bits);uint64_t htobe64(uint64_t host_64bits); uint64_t htole64(uint64_t host_64bits); uint64_t be64toh(uint64_t big_endian_64bits); uint64_t le64toh(uint64_t little_endian_64bits);Boost
Boost.Endian: The Boost Endian Library - 1.77.0
References
byteorder(3) - Linux manual page (man7.org)
endian(3) - Linux manual page (man7.org)
Boost.Endian: The Boost Endian Library - 1.77.0
總結(jié)
- 上一篇: 电子招标采购系统源码 + 二次开发+定制
- 下一篇: 如何将多个doc文档合并在一起