大小端問題

2021-07-04 05:53:35 字數 2229 閱讀 9340

大小端問題

最近工作中,有兩次遇到大小端問題,所以花時間寫這篇日誌,總結一下。

1.      實際需求

(1) 前段時間寫了乙個修復損壞的gzip檔案的tool,在linux server上編譯執行沒有問題。但是在solaris server上運編譯執行,結果總是和預期的不一致,跟蹤發現是由大小端問題導致的;

(2) 最近在寫乙個跨平台的編譯指令碼,編譯引數裡有目標可執行程式執行平台大小端這個引數;

2.     大小端解析

端模式出自jonathan swift書寫的《格列佛遊記》一書,這本書根據將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為big endian,從尖頭開始將雞蛋敲開的人被歸為littile endian。小人國的內戰就源於吃雞蛋時是究竟從大頭(big-endian)敲開還是從小頭(little-endian)敲開。

在計算機業big endian和little endian也幾乎引起一場戰爭。在計算機業界,endian表示資料在儲存器中的存放順序。

大端:高位存在低位址,低位存在高位址;

小端:高位存在高位址,低位存在低位址;(intel的x86,arm普遍都是屬於小端)

舉個例子,從記憶體位址0x0000開始有以下資料

0x0000    0x12

0x0001    0x34

0x0002    0xab

0x0003    0xcd

如果我們去讀取乙個位址為0x0000的四個位元組變數:

若位元組序為big-endian,則讀出結果為0x1234abcd;

若位元組序位little-endian,則讀出結果為0xcdab3412.

如果我們將0x1234abcd寫入到以0x0000開始的記憶體中,則結果為:

big-endian      little-endian

0x0000          0x12                  0xcd

0x0001          0x23                  0xab

0x0002          0xab                  0x34

0x0003          0xcd                  0x12

intelx86系列以及arm系列cpu都是little-endian的位元組序.

3.    大小端問題的解決

(1) 下面貼乙個很簡單的判斷大小端的函式

int checkcpuendian()//返回1,為小端;反之,為大端;

c; c.a = 1;

return 1 == c.b;

}

(2) 大端模式處理器的位元組序到網路位元組序不需要轉換,此時ntohs(n)=n,ntohl =n;而小端模式處理器的位元組序到網路位元組必須要進行轉換(同理,有時候需要將大端位元組順序轉換成小端位元組順序,也用這個函式,因為這個函式本來就是用來顛倒位元組順序的),轉換如下:

#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 htohl

#else

#error either big_endian or little_endian must be #defined, but not both.

#endif

大小端問題:

大小端問題

對於位數大於 8位的處理器,例如 16位或者 32位的處理器,由於暫存器寬度大於乙個位元組,那麼必然存在著乙個如果將多個位元組安排的問題。因此就導致了大端儲存模式和小端儲存模式。例如乙個 16bit 的short型x 在記憶體中的位址為 0x0010,x 的值為0x1122 那麼0x11 為高位元組...

大小端問題

大小端問題 跨位元組位域大小端轉換例項講解 注 結構體整體當做u16 u32來賦值時才會產生這種問題,如果是按位元組或者移位方式訪問則沒有問題 typedef struct s bit sample 測試程式 vos void bigendiandomainfiledtest vos void 1 ...

大小端問題

什麼是大小端 大小端表示資料在儲存器中的存放順序 1 小端模式 資料的高位元組儲存在記憶體的高位址中,而低位元組儲存在記憶體的低位址中。這種儲存模式將位址的高低和資料位權有效的結合起來,高位址部分權值高,低位址部分權值低,和我們平常的邏輯方法一致。2 大端模式 資料的高位元組儲存在記憶體的低位址中,...