判斷big endian和little endian的方法

 
不一樣體系的CPU在內存中的數據存儲每每存在着差別。例如,Intel的x86系列處理器將低序字節存儲在起始地址,而一些RISC架構的處理器,如IBM的370主機使用的PowerPC或Motorola公司生產的CPU,都將高序字節存儲在起始位置。這兩種不一樣的存儲方式被稱爲little-endian和big-endian。
little-endian是x86系列CPU的數據存儲方式,即將低序的部分存儲在前面。而big-endian是將高序部分存儲在前面。例如,要存儲0xF432,little-endian將以32F4存儲,而使用big-endian與此相反,將存儲爲F432,如圖13.2所示。
程序p13.1.c講解了如何判斷系統是使用big-endian仍是little-endian實現數據存儲的。程序中使用的方法以下所示。
 
 
圖13.2   big-endian與little-endian方式數據存儲示例
(1)利用聯合的特色。聯合中的數據成員是共享存儲空間的,所分配的空間爲數據成員中最大所需的內存數。程序定義了名爲endian_un的聯合體,其中包含兩個數據成員,一個是short類型的數據成員(在32位系統上,short類型的長度是2字節),一個是字符類型的字符數組,字符數組的元素個數爲short類型的字節數。
程序將var賦值爲0x0102。因爲聯合結構的特色,bits字符串數組中一樣存儲了0x0102這一數值。經過判斷字符串中的低位和高位存儲的內容,就能夠知道系統是little-endian仍是big-endian的。

#includehtml

int main(int argc, char **argv)  {          union {            short  s;        char   c[sizeof(short)];      } un;web

        un.s = 0x0102;          if (sizeof(short) == 2) {                  if (un.c[0] == 1 && un.c[1] == 2)                          printf("big-endian\n");                  else if (un.c[0] == 2 && un.c[1] == 1)                          printf("little-endian\n");                  else                          printf("unknown\n");          } else                  printf("sizeof(short) = %d\n", sizeof(short));編程

        exit(0);  }數組

 

(2)經過強制類型轉換實現。程序中經過取flag變量的地址,得到起始空間的存儲內容。若是起始空間存儲的是數據的低位內容,則表示存儲方式爲little-endian,不然爲big-endian。
程序的具體代碼以下:
//使用類型的強制轉換實現little-endian與big-endian的判斷
int is_little_endian(void)
{
  unsigned short flag=0x4321;
  if (*(unsigned char*)&flag==0x21)
    return 1;
  else
    return 0;
}

使用gcc編譯p13.1.c,得到名爲p13.1的可執行文件。執行該程序,具體輸出以下。能夠看到x86系統的內存數據存儲方式爲little-endian方式。
[program@localhost charter13]$ gcc -o p13.1 p13.1.c 
[program@localhost charter13]$ ./p13.1 
judged by first method, little-endian
judged by second method, little-endian
[program@localhost charter13]$
之因此介紹big-endian和little-endian,是由於這一數據存儲方式不只影響程序在不一樣硬件平臺中的移植,並且在網絡編程中也要考慮字節順序的問題。爲了不兼容性的問題,網絡中的數據傳輸都使用了從高到低的順序存儲方式。所以,若是要將數據從低位字節優先(little-endian)的機器上發往網絡,必須首先進行轉換。而big-endian的機器是不須要轉換的。
Linux系統提供了htons、htonl、ntohs、ntoh這4個函數用於進行字節順序的轉換。其中,h是host的縮寫,n表示network。最後一個字符若是是s,表示short類型,若是是l,表示爲long類型。4個函數的具體定義以下: uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);   htonl/htons:表示主機字節順序轉換成網絡字節順序,htonl函數和htons函數的區別在於參數長度存在差別。   ntohl/ntohs:表示網絡字節順序轉換成主機字節順序,ntohl函數和ntohs函數的區別在於參數長度存在差別。
相關文章
相關標籤/搜索