2009/01/30

Big Endian和Little Endian的比較(2015/9/15更新)

endian指的是當物理上的最小單元比邏輯上的最小單元還要更小時,邏輯單元對映到物理單元的排布關係。

這篇文章將說明 Big Endian 和 Little Endian 的差異,並以一段 C 語言做範例。

Big Endian 和 Little Endian 的實例


如果你在文件上看到一個雙字組的data,Ex: long MyData=0x12345678,要寫到從0x0000開始的記憶體位址時。
  1. 如果是Big Endian的系統:
    存到記憶體會變成 0x12 0x34 0x56 0x78,最高位元組在位址最低位元,最低位元組在位址最高位元,依次排列。
  2. 如果是Little Endian的系統:
    存到記憶體會變成 0x78 0x56 0x34 0x12,最低位元組在最低位元,最高位元組在最高位元,反序排列。
比較的結果就是這樣:
big-endianlittle-endian
0x00000x120x78
0x00010x340x56
0x00020x560x34
0x00030x780x12

Big Endian 和 Little Endian 的差異


以目前常見的CPU為例:
  • INTEL X86、DEC VAX 使用 LITTLE-ENDIAN 設計;
  • HP、IBM、MOTOROLA 68K 系列使用 BIG-ENDIAN 設計;
  • POWERPC 同時支援兩種格式,稱為 BI-ENDIAN。
另外,以我目前在SID測試的程式testendian.c為例,我必須在以下的三個地方都必須指定Endian,否則即使Build時可以通過,但在計算時就可能會出現問題,因為放入記憶體內的資料可能是反過來的。
  1. 在Compile時
    就必須先指定是要採用那種Endian,如果不指定,會使用內定值;
  2. 在ToolChain內
    也必須指定是要採用那種Endian,如果不指定,也會使用內定值;
  3. 在SID內
    也是由設定來決定Endian,所以在模擬CPU的Configuration內也必須指定是要採用那種Endian。

Big Endian 和 Little Endian 的範例 testendian.c


#include <stdio.h>
typedef union { long l; unsigned char c[4]; } EndianTest;
int main(int argc, char* argv[]) {
 EndianTest a;
 a.l=0x12345678;
 int i=0;
 if(a.c[0]==0x78 && a.c[1]==0x56 && a.c[2]==0x34 && a.c[3]==0x12) {
 printf("This system is 'Little Endian'.\n"); }
 else if(a.c[0]==0x12 && a.c[1]==0x34 && a.c[2]==0x56 && a.c[3]==0x78) {
 printf("This system is 'Big Endian'.\n"); }
 else {printf("This system is 'Unknown Endian'.\n"); }
 printf("for a long variable value is 0x%lX\n",a.l);
 printf("and its storage order in memory :\n");
 for(i=0;i<4;i++) printf("%p : 0x%02X\n",&a.c[i],a.c[i]);  // getchar(); // wait for a key ..。  return 0; }

  1. 為啥叫Big/Little Endian?那是個還挺有趣的故事,有興趣的朋友可以參考這裡的最後一段。
  2. Big-Endian 和 Little-Endian 两者概念的区别
  3. 用 C 語言窺探記憶體

16 則留言:

  1. 應該是下面這樣吧!
    如果是Big Endian的系統,存到記憶體會變成 0x12 0x34 0x56 0x78
    如果是Little Endian的系統,存到記憶體會變成 0x78 0x56 0x34 0x12

    回覆刪除
  2. 沒錯 paul講的沒錯~~~

    回覆刪除
  3. 我比較感興趣的是, 你原來寫了什麼? :b

    回覆刪除
  4. To Satami,

    我改的部份是將段落的次序重新編排,讓讀者讀起來思路更順暢。

    回覆刪除
  5. 不是啦! 我是說 Paul 修正了什麼? :)

    回覆刪除
  6. 我原本寫的內容中,存到記憶體的結果剛好寫相反了!

    回覆刪除
  7. 您解釋的很好
    例子也很棒 淺顯易懂
    感謝!!

    回覆刪除
  8. To Chun Yu,
    這個例子不是我設計的,我只是用這個例子再改寫成可以實際執行,倘若能夠對讀者有幫助,就是我最大的心願了。

    回覆刪除
  9. To 九樓的匿名:
    不知道該怎麼回耶...

    回覆刪除
  10. 我到底該選unicode還是unicode big endian?

    回覆刪除
  11. To 11樓的Maggie Wu:
    對一般人而言,不大會遇到這個問題。我不知道你打算怎麼用?所以不大知道該怎麼回耶...

    回覆刪除
  12. 他叫我選unicode

    那有2種選哪ㄍ

    unicode又是什ㄇ意思?

    我打ㄌ標點符號他要我選才不流失存

    笨電腦!

    回覆刪除
  13. 我要無條件擋掉色情信!

    怎ㄇ擋?

    可以破解GMAIL自己擋ㄇ?
    連垃圾桶都進不來ㄉ!


    please teach me!

    回覆刪除
  14. To 11樓的Maggie Wu:
    unicode和Big/Little Endian沒啥關係呀!

    回覆刪除
  15. To 11樓的Maggie Wu:
    你可以參考一下這個網頁呀!
    http://homework.mhups.tp.edu.tw/web/gmail/Gmail%E6%95%99%E5%AD%B8%28%E5%85%AD%29-%E5%9E%83%E5%9C%BE%E9%83%B5%E4%BB%B6.htm

    回覆刪除