關於Big Endian 和 Little Endian

一、字節序

來自: http://ayazh.gjjblog.com/archives/1058846/

談到字節序的問題,必然牽涉到兩大 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 方式稱之爲網絡字節序。當兩臺採用不同字節序的主機通信時,在發送數據之前都必須經過字節序的轉換成爲網絡字節序後再進行傳輸。ANSI C 中提供了下面四個轉換字節序的宏。

big endian :最高字節在地址最低位,最低字節在地址最高位,依次排列。
little endian
:最低字節在最低位,最高字節在最高位,反序排列。

endian 指的是當物理上的最小單元比邏輯上的最小單元小時,邏輯到物理的單元排布關係。咱們接觸到的物理單元最小都是byte ,在通信領域中,這裏往往是bit ,不過原理也是類似的。

一個例子:
如果我們將0x1234abcd 寫入到以0x0000 開始的內存中,則結果爲
                big-endian     little-endian
0x0000     0x12              0xcd
0x0001     0x34              0xab
0x0002     0xab              0x34
0x0003     0xcd              0x12

目前應該little endian 是主流,因爲在數據類型轉換的時候(尤其是指針轉換)不用考慮地址問題。

 

二、 Big Endian Little Endian 名詞的由來

這兩個術語來自於  Jonathan Swift  的《《格利佛遊記》其中交戰的兩個派別無法就應該從哪一端--小端還是大端--打開一個半熟的雞蛋達成一致。:)

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

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


在那個時代, Swift 是在諷刺英國和法國之間的持續衝突, Danny Cohen ,一位網絡協議的早期開創者,第一次使用這兩個術語來指代字節順序,後來這個術語被廣泛接納了

 

三、 Big Endian Little Endian 優劣

來自: Dr. William T. Verts, April 19, 1996

Big Endian

判別一個數的正負很容易,只要取 offset0 處的一個字節就能確認。

Little Endian

長度爲 1 2 4 字節的數,排列方式都是一樣的,數據類型轉換非常方便。

 

四、一些常見文件的字節序

來自: Dr. William T. Verts, April 19, 1996

 

Common file formats and their endian order are as follows:

  • Adobe Photoshop -- Big Endian
  • BMP (Windows and OS/2 Bitmaps) -- Little Endian
  • DXF (AutoCad) -- Variable
  • GIF -- Little Endian
  • IMG (GEM Raster) -- Big Endian
  • JPEG -- Big Endian
  • FLI (Autodesk Animator) -- Little Endian
  • MacPaint -- Big Endian
  • PCX (PC Paintbrush) -- Little Endian
  • PostScript -- Not Applicable (text!)
  • POV (Persistence of Vision ray-tracer) -- Not Applicable (text!)
  • QTM (Quicktime Movies) -- Little Endian (on a Mac!) PeterLeeBig Endian in my opinion
  • Microsoft RIFF (.WAV & .AVI) -- Both
  • Microsoft RTF (Rich Text Format) -- Little Endian
  • SGI (Silicon Graphics) -- Big Endian
  • Sun Raster -- Big Endian
  • TGA (Targa) -- Little Endian
  • TIFF -- Both, Endian identifier encoded into file
  • WPG (WordPerfect Graphics Metafile) -- Big Endian (on a PC!)
  • XWD (X Window Dump) -- Both, Endian identifier encoded into file

五、比特序

來自: http://ayazh.gjjblog.com/archives/1058846/

我在89 號的《Big EndianLittle Endian 》一文中談了字節序的問題。可是有朋友仍然會問,CPU 存儲一個字節的數據時其字節內的8 個比特之間的順序是否也有big endianlittle endian 之分?或者說是否有比特序的不同?  

    
實際上,這個比特序是同樣存在的。下面以數字0xB410110100 )用圖加以說明。


Big Endian

   msb                                                         lsb
   ---------------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   1  |   0  |   1  |   1  |   0  |   1  |   0  |   0  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

   lsb                                                         msb
   ---------------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   0  |   0  |   1  |   0  |   1  |   1  |   0  |   1  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    
實際上,由於CPU 存儲數據操作的最小單位是一個字節,其內部的比特序是什麼樣對我們的程序來說是一個黑盒子。也就是說,你給我一個指向0xB4 這個數的指針,對於big endian 方式的CPU 來說,它是從左往右依次讀取這個數的8 個比特;而對於little endian 方式的CPU 來說,則正好相反,是從右往左依次讀取這個數的8 個比特。而我們的程序通過這個指針訪問後得到的數就是0xB4 ,字節內部的比特序對於程序來說是不可見的,其實這點對於單機上的字節序來說也是一樣的。

 
    那可能有人又會問,如果是網絡傳輸呢?會不會出問題?是不是也要通過什麼函數轉換一下比特序?嗯,這個問題提得很好。假設little endian 方式的CPU 要傳給big endian 方式CPU 一個字節的話,其本身在傳輸之前會在本地就讀出這個8 比特的數,然後再按照網絡字節序的順序來傳輸這8 個比特,這樣的話到了接收端不會出現任何問題。而假如要傳輸一個32 比特的數的話,由於這個數在littel endian 方存儲時佔了4 個字節,而網絡傳輸是以字節爲單位進行的,little endian 方的CPU 讀出第一個字節後發送,實際上這個字節是原數的LSB ,到了接收方反倒成了MSB 從而發生混亂。

 

轉自:http://blog.csdn.net/sunshine314/2008/4/20/2309655.aspx

發佈了19 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章