大端格式和小端格式
一、概念:
不同的CPU有不同的字節序類型,指在內存中的保存順序。
常見的有兩種:
1.Little-endian: 將低序字節存儲在起始地址(低位編碼,低位開始);
2.Big-endian: 將高序字節存儲在起始位置(高位編碼,高位開始);
LE(little-endian):
符合人的思維的字節序
地址低位存儲值的低位
地址高位存儲值的高位
BE(big-endian):
直觀的字節序
地址低位存儲值的高位
地址高位存儲值得低位
二、例子:
0x01020304 (DWORD)在內存地址4000 4001 4002 4003的存儲方式:
內存地址:4000 40014002 4003
LE:04 03 02 01
BE:01 02 03 04
注:每個地址存1個字節,每個字有4個字節。2位16進制數是1個字節(0xFF = 1111 1111)
三、注意:
1.x86系列的CPU都是little-endian的字節序;
2.一般操作系統都是小端,而通信協議是大端的;
3.創建CPU的字節序:
Big-Endian: PowerPC、IBM、Sun
Little-Endian:x86、DEC
ARM既可以工作在大端模式,也可以工作在小端模式。
4.常見的文件的字節序:
Adobe PS : Big Endian
BMP: Little Endian
DXF(AutoCAD):Variable
GIF:Little Endian
JPEG:Little Endian
MacPaint: Big Endian
RTF:Little Endian
四、工具:
1.判斷機器的字節序:
BOOL isBigEndian()
{
int a = 0x1234;
// 通過將int強制類型轉換成char單字節,通過判斷其實存儲位置
char b = *(char *)&a;
if (b == 0x12) {
return YES;
}
return NO;
}
2.聯合體 union的存放順序死所有的成員都從地地址開始存放,利用該特性就可以輕鬆獲得CPU對內存採用的Little-endian還是Big-endian模式讀寫:
BOO isBigEndian()
{
union NUM
{
int a;
char b;
} num;
num.a = 0x1234;
if (num.b == 0x12) {
return YES;
}
return NO;
}
/**
* @brief 64位數據高度和低地址的交換
*
* @param A 值
*
* @return 返回結果
*/
#define BigSwapLittle64(A) ((((uint64)(A) & 0xff00000000000000) >> 56) | \
(((uint64)(A) & 0x00ff000000000000) >>40) | \
(((uint64)(A) & 0x0000ff0000000000) >>24) | \
(((uint64)(A) & 0x000000ff00000000) >>8) | \
(((uint64)(A) & 0x00000000ff000000) <<8) | \
(((uint64)(A) & 0x0000000000ff0000) <<24) | \
(((uint64)(A) & 0x000000000000ff00) <<40) | \
(((uint64)(A) & 0x00000000000000ff) <<56))
/**
* @brief 32位數據高度和低地址的交換
*
* @param A 值
*
* @return 返回結果
*/
#define BigSwapLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | \
(((uint32)(A) & 0x00ff0000) >>8) | \
(((uint32)(A) & 0x0000ff00) <<8) | \
(((uint32)(A) & 0x000000ff) <<24))
/**
* @brief 16位數據高度和低地址的交換
*
* @param A 值
*
* @return 返回結果
*/
#define BigSwapLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) <<8))
五、備註參考:
1.http://www.cnblogs.com/passingcloudss/archive/2011/05/03/2035273.html
2.http://blog.csdn.net/goldfighter/article/details/8289215