大小端學習
一、什麼是大端和小端
所謂的大端模式,就是高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。
所謂的小端模式,就是低位位元組排放在記憶體的低地址端,高位位元組排放在記憶體的高地址端。
簡單來說:大端——高尾端,小端——低尾端
舉個例子,比如數字 0x12 34 56 78在記憶體中的表示形式為:
1)大端模式:
低地址 -----------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
2)小端模式:
低地址 ------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12
可見,大端模式和字串的儲存模式類似。
3)下面是兩個具體例子:
16bit寬的數0x1234在Little-endian模式(以及Big-endian模式)CPU記憶體中的存放方式(假設從地址0x4000開始存放)為:
記憶體地址 小端模式存放內容 大端模式存放內容
0x4000 0x34 0x12
0x4001 0x12 0x34
32bit寬的數0x12345678在Little-endian模式以及Big-endian模式)CPU記憶體中的存放方式(假設從地址0x4000開始存放)為:
記憶體地址 小端模式存放內容 大端模式存放內容
0x4000 0x78 0x12
0x4001 0x56 0x34
0x4002 0x34 0x56
0x4003 0x12 0x78
4)大端小端沒有誰優誰劣,各自優勢便是對方劣勢:
小端模式 :強制轉換資料不需要調整位元組內容,1、2、4位元組的儲存方式一樣。
大端模式 :符號位的判定固定為第一個位元組,容易判斷正負。
二、如何判斷機器的位元組序
一般都是通過 union 來測試的,下面這段程式碼可以用來測試一下你的編譯器是大端模式還是小端模式:
#include
int main (void)
{
union
{
short i;
char a[2];
}u;
u.a[0] = 0x11;
u.a[1] = 0x22;
printf ("0x%x\n", u.i); //0x2211 為小端 0x1122 為大端
return 0;
}
輸出結果:
0x2211
union 型資料所佔的空間等於其最大的成員所佔的空間。對 union 型的成員的存取都是相對於該聯合體基地址的偏移量為 0 處開始,也就是聯合體的訪問不論對哪個變數的存取都是從 union 的首地址位置開始。
聯合是一個在同一個儲存空間裡儲存不同型別資料的資料型別。這些儲存區的地址都是一樣的,聯合裡不同儲存區的記憶體是重疊的,修改了任何一個其他的會受影響。
當然你也可以這樣
#include
int main (void)
{
short i = 0x1122;
char *a = (char*)(&i);
printf ("0x%x\n", *(a + 0)); //大端為 0x11 小端為 0x22
printf ("0x%x\n", *(a + 1));
return 0;
}
輸出結果:
0x22
0x11
說明:上面兩個例子,可以通過 if 語句來判斷大小端,這裡只是介紹方法。
三、常見的位元組序
一般作業系統都是小端,而通訊協議是大端的。
1)常見CPU的位元組序
Big Endian : PowerPC、IBM、Sun
Little Endian : x86、DEC
ARM既可以工作在大端模式,也可以工作在小端模式。
2)常見檔案的位元組序
Adobe PS – Big Endian
BMP – Little Endian
DXF(AutoCAD) – Variable
GIF – Little Endian
JPEG – Big Endian
MacPaint – Big Endian
RTF – Little Endian
另外,Java和所有的網路通訊協議都是使用Big-Endian的編碼。
使用 htonl, htons, ntohl, ntohs 等函式 這個可以參考我的網路程式設計部分的知識第一節 深入淺出TCPIP之理解TCP報文格式和互動流程
htonl() //32位無符號整型的主機位元組順序到網路位元組順序的轉換(小端->>大端)
htons() //16位無符號短整型的主機位元組順序到網路位元組順序的轉換 (小端->>大端)
ntohl() //32位無符號整型的網路位元組順序到主機位元組順序的轉換 (大端->>小端)
ntohs() //16位無符號短整型的網路位元組順序到主機位元組順序的轉換 (大端->>小端)
參考部落格:https://blog.csdn.net/weixin_39789792/article/details/112128845?utm_term=arm%E5%B0%8F%E7%AB%AF%E8%BF%98%E6%98%AF%E5%A4%A7%E7%AB%AF&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-2-112128845&spm=3001.4430