判斷一臺機器是大端序還是小端序

在幾乎所有的機器上,多字節對象都被存儲爲連續的字節序列。例如在C語言中,一個類型爲int的變量x地址爲0x100,那麼其對應地址表達式&x的值爲0x100。且x的四個字節將被存儲在存儲器0x100, 0x101, 0x102, 0x103位置。

而存儲地址內的排列則有兩個通用規則。一個多位的整數將按照其存儲地址的最低或最高字節排列。如果最低有效字節最高有效字節的前面,則稱小端序;反之則稱大端序。在網絡應用中,字節序是一個必須被考慮的因素,因爲不同機器類型可能採用不同標準的字節序,所以均按照網絡標準轉化。

例如假設上述變量x類型爲int,位於地址0x100處,它的十六進制爲0x01234567,地址範圍爲0x100~0x103字節,其內部排列順序依賴於機器的類型。大端法從首位開始將是:0x100: 01, 0x101: 23,..。而小端法將是:0x100: 67, 0x101: 45,..

對於單一的字節(a byte),大部分處理器以相同的順序處理位元(bit),因此單字節的存放方法和傳輸方式一般相同。

對於多字節數據,如整數(32位機中一般佔4字節),在不同的處理器的存放方式主要有兩種,以內存中0x0A0B0C0D的存放方式爲例,分別有以下幾種方式:

注: 0x前綴代表十六進制。

大端序

大端序(英:big-endian)或稱大尾序

Big-Endian.svg
  • 數據以8bit爲單位:
地址增長方向  →
... 0x0A 0x0B 0x0C 0x0D ...

示例中,最高位字節是0x0A 存儲在最低的內存地址處。下一個字節0x0B存在後面的地址處。正類似於十六進制字節從左到右的閱讀順序。

  • 數據以16bit爲單位:
地址增長方向  →
... 0x0A0B 0x0C0D ...

最高的16bit單元0x0A0B存儲在低位。

小端序

小端序(英:little-endian)或稱小尾序

Little-Endian.svg
  • 數據以8bit爲單位:
地址增長方向  →
... 0x0D 0x0C 0x0B 0x0A ...

最低位字節是0x0D 存儲在最低的內存地址處。後面字節依次存在後面的地址處。

  • 數據以16bit爲單位:
地址增長方向  →
... 0x0C0D 0x0A0B ...

最低的16bit單元0x0D0C存儲在低位。

  • 更改地址的增長方向:

當更改地址的增長方向,使之由右至左時,表格更具有可閱讀性。

←  地址增長方向
... 0x0A 0x0B 0x0C 0x0D ...

最低有效位(LSB)是0x0D 存儲在最低的內存地址處。後面字節依次存在後面的地址處。

←  地址增長方向
... 0x0A0B 0x0C0D ...

最低的16bit單元0x0C0D存儲在低位。

混合序

混合序(英:middle-endian)具有更復雜的順序。以PDP-11爲例,0x0A0B0C0D被存儲爲:

  • 32bit在PDP-11的存儲方式
地址增長方向  →
... 0x0B 0x0A 0x0D 0x0C ...

可以看作最高的16bit位和低位以大端序存儲,但16bit內部以小端存儲。

參考地址:http://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F



存儲模式:大端模式和小端模式。

大端模式(Big_endian):字數據的高字節存儲在低地址中,而字數據的低字節則存放在高地址中。

小端模式(Little_endian):字數據的高字節存儲在高地址中,而字數據的低字節則存放在低地址中。

union型數據所佔的空間等於其最大的成員所佔的空間。對union型的成員的存取都是相對於該聯合體基地址的偏移量爲0處開始,也就是聯合體的訪問不論對哪個變量的存取都
是從union的首地址位置開始.

請寫一個C函數,若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1。

先分析一下,按照上面關於大小端模式的定義,假設int類型變量i被初始化爲1。

以大端模式存儲,其內存佈局如下圖:

以小端模式存儲,其內存佈局如下圖:

變量i佔4個字節,但只有一個字節的值爲1,另外三個字節的值都爲0。如果取出低地址上的值爲0,毫無疑問,這是大端模式;如果取出低地址上的值爲1,毫無疑問,這是
小端模式

int checkSystem( )
{
     union check
    {
         int i;
         char ch;
       }c;
     c.i = 1;
     return (c.ch ==1);
}

另外一種判斷大端小端的方法

//判斷程序如下:
#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1
int TestByteOrder(){
    short int word = 0x0001;
    char *byte = (char *) &word;
    return (byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}
原文地址:http://www.cricode.com/2392.html





  1. int checkSystem( )  
  2. {  
  3.      union check  
  4.     {  
  5.          int i;  
  6.          char ch;  
  7.        }c;  
  8.      c.i = 1;  
  9.      return (c.ch ==1);  
  10. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章