什麼是Big Endian和Little Endian

1.故事的起源

“endian”這個詞出自《格列佛遊記》。小人國的內戰就源於喫雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。

我們一般將endian翻譯成“字節序”,將big endian和little endian稱作“大尾”和“小尾”。

2.什麼是Big Endian和Little Endian?

在設計計算機系統的時候,有兩種處理內存中數據的方法。一種叫爲little-endian,存放在內存中最低位的數值是來自數據的最右邊部分(也就是數據的最低位部分)。比如一個16進制數字0x12345678,在內存存放的方式如下:

0111,1000

0101,0110

0011,0100

0001,0010

地址

100

101

102

103

            另一種稱爲big-endian,正好相反,存放在內存中最低位的數值是來自數據的最左邊邊部分(也就是數據的最高爲部分)。比如一個16進制數字0x12345678,在內存存放的方式如下:

0001,0010

0011,0100

0101,0110

0111,1000

地址

100

101

102

103

比如某些文件需要在不同平臺處理,或者通過Socket通信。這方面我們可以藉助ntohl(), ntohs(), htonl(), and htons()函數進行格式轉換。

3.如何判斷系統是Big Endian還是Little Endian?

在/usr/include/中(包括子目錄)查找字符串BYTE_ORDER(或_BYTE_ORDER, __BYTE_ORDER),確定其值。這個值一般在endian.h或machine/endian.h文件中可以找到,有時在feature.h中,不同的操作系統可能有所不同。一般來說,Little Endian系統BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)爲1234,Big Endian系統爲4321。大部分用戶的操作系統(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本質上說,Little Endian還是Big Endian與操作系統和芯片類型都有關係。

======================================================================

ext3 文件系統在硬盤分區上的數據是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平臺上開發 ext3 相關的程序,要特別注意這一點。

談到字節序的問題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列採用big endian方式存儲數據,而x86系列則採用little endian方式存儲數據。那麼究竟什麼是big endian,什麼又是little endian呢?

     其實big endian是指低地址存放最高有效字節(MSB),而little endian則是低地址存放最低有效字節(LSB)。

     用文字說明可能比較抽象,下面用圖像加以說明。比如數字0x12345678在兩種不同字節序CPU中的存儲順序如下所示:

Big Endian

   低地址                                            高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     12     |      34    |     56      |     78    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

   低地址                                            高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     78     |      56    |     34      |     12    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

     從上面兩圖可以看出,採用big endian方式存儲數據是符合我們人類的思維習慣的。而little endian,!@#$%^&*,見鬼去吧 -_-|||

     爲什麼要注意字節序的問題呢?你可能這麼問。當然,如果你寫的程序只在單機環境下面運行,並且不和別人的程序打交道,那麼你完全可以忽略字節序的存在。但是,如果你的程序要跟別人的程序產生交互呢?在這裏我想說說兩種語言。C/C++語言編寫的程序裏數據存儲順序是跟編譯平臺所在的CPU相關的,而JAVA編寫的程序則唯一採用big endian方式來存儲數據。試想,如果你用C/C++語言在x86平臺下編寫的程序跟別人的JAVA程序互通時會產生什麼結果?就拿上面的0x12345678來說,你的程序傳遞給別人的一個數據,將指向0x12345678的指針傳給了JAVA程序,由於JAVA採取big endian方式存儲數據,很自然的它會將你的數據翻譯爲0x78563412。什麼?竟然變成另外一個數字了?是的,就是這種後果。因此,在你的C程序傳給JAVA程序之前有必要進行字節序的轉換工作。

     無獨有偶,所有網絡協議也都是採用big endian的方式來傳輸數據的。所以有時我們也會把big endian方式稱之爲網絡字節序。當兩臺採用不同字節序的主機通信時,在發送數據之前都必須經過字節序的轉換成爲網絡字節序後再進行傳輸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章