little-endian

了解Big Endian 及 Little Endian


更新記錄

item note
20160304 第一版
20170512 增加: Network Byte Order

目錄


Little Endian / Big Endian

如圖中所示,,a變數數值為0x12345678,此時存入記意体中方式有下例兩種

比較圖

  • Little Endian

    - 由LSB(即低位元)數值取出,開始放入記憶体位/或檔案
    - 因此讀記憶体/檔案時(先取到LSB),只要依序 即可轉出正確數值
    
  • Big Endian

    - 由MSB(即高位元)數值取出,開始放入記意体位/或檔案
    - 因此讀記憶体/檔案時(先取到MSB),只要換一下順序,才能轉出正確數值
    
  • 由CPU來決定採用那種方式處理(在記憶体/或存入檔案,方式:Little Ednain/ Big Endian)

MSB (most significant bit) 為最高有效位元
LSB (least significant bit) 為最低有效位元

如何測試此CPU為何種

  • source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
typedef union { long l; unsigned char c[4]; } EndianTest;
void main(void){
EndianTest a;
int i=0;

a.l = 0x12345678;
if( a.c[0] == 0x78 && a.c[1] == 0x56 && a.c[2] == 0x34 && a.c[3] == 0x12 ){
printf(" Little Endian \n");
}
else if( a.c[0] == 0x12 && a.c[1] == 0x34 && a.c[2] == 0x56 && a.c[3] == 0x78 ){
printf(" Big Endian \n");
}
else
printf(" Unknown Endian\n");

printf(" long variable is 0x%1X\n", a.l);
for(i=0; i<4; i++) printf("%p : 0x%02X\n",&a.c[i],a.c[i]);
}
  • ubuntu 32bit (intel cpu) test

    1
    2
    3
    4
    5
    6
     Little Endian
    long variable is 0x12345678
    0xff929d18 : 0x78
    0xff929d19 : 0x56
    0xff929d1a : 0x34
    0xff929d1b : 0x12
  • hisi3521

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     /tmp/tt# ./test-1 

    Little Endian
    long variable is 0x12345678
    0xbef24c8c : 0x78
    0xbef24c8d : 0x56
    0xbef24c8e : 0x34
    0xbef24c8f : 0x12
    /tmp/tt#
    /tmp/tt#

Network Byte Order

來源:3.2. Byte Order(位元組順序)

  • Big-Endian 又稱為 Network Byte Order,因為這個順序與我們網路類型順序一樣
  • 你的電腦會以 Host Byte Order 儲存數字,如果是 Intel 80x86,Host Byte Order 是 Little-Endian
  • 全部電腦的 Host Byte Order 都不是 Network Byte Order,然後每次都用函式將值轉換為 Network Byte Order。如果有必要,函式會發動魔法般的轉換,而這個方式會讓你的程式碼能更方便地移植到不同 endian 的機器
1
2
3
4
htons() host to network short
htonl() host to network long
ntohs() network to host short
ntohl() network to host long

參考來源