高位元組優先,低位元組優先

來源:互聯網
上載者:User

自第一台電腦誕生,其最小儲存單元就被永久的定格了——一個由8個位元(bit)組成的稱為位元組(byte)的單位。電腦的所有記憶體以位元組數組的方式進行編址。

 

當一個邏輯上長於一個位元組的整形資料放置在記憶體中時(比如16位,32位,和64位的整數),電腦設計者需要考慮這些位元組的儲存順序。一些體繫結構的設計者選擇了將位元組的邏輯順序與物理順序一致,即將邏輯上較低的位元組放置在物理上較低的位元組上;另外一些設計者則選擇了將位元組的邏輯順序與物理順序相反,即將邏輯上較低的位元組放置在物理上較高的位元組上。前者被稱為“little endian”,比如Intel x86系列;後者則被稱為“big endian”,比如Motorola的PowerPC以及Sun Sparc。還有一些平台同時支援兩種方案,由開發人員決定使用哪一種。

 

兩種選擇為底層開發人員帶來了一定的困擾。比如,兩個位元組順序不一致的平台之間進行通訊,或者在兩個位元組順序不一致的平台之間移植系統。這都是跨平台的例子,對於這些情況,位元組順序的問題是不能迴避的。對於僅僅在一種平台上進行開發的程式員而言,如果它能夠避免強制類型轉換(比如將位元組數組強制轉換為一個長整數),一貫的以邏輯順序來操作大於一個位元組的整數,應該可以迴避這個問題。但由於C語言是一種非常靈活的語言,有時候通過強制類型轉換可以讓代碼非常精簡,甚至達到非常巧妙的效果,所以,要求C程式員完全迴避這個問題,幾乎是不現實的。

 

由於Little Endian提供了邏輯順序與物理順序的一致性,讓編程者擺脫了不一致性所帶來的困擾,C語言開發人員可以無所顧忌的按照自己的意願進行強制類型轉換,所以現代體繫結構幾乎都支援Little Endian。但Big Endian也有其優點,尤其對於組譯工具員:他們對於任意長度的整數,總是可以通過判斷Byte 0的bit-7來查看一個整數的正負;對於Little Endian則不得不首Crowdsourced Security Testing道當前整數的長度,然後查看最高byte的bit-7來判斷其正負。對於這種情況,big endian的開發人員可以寫出非常高效的代碼。

 

兩派的支援者爭論不休,正像他們所支援名詞(big endian和little endian)的典故所講述的那樣:Little Endian和Big Endian這兩個名詞來源於Jonathan Swift的《格利佛遊記》其中交戰的兩個派別無法就應該從哪一端--小端還是大端--開啟一個半熟的雞蛋達成一致。:)在那個時代,Swift是在諷刺英國和法國之間的持續衝突,Danny Cohen,一位網路通訊協定的早期開創者,第一次使用這兩個術語來指代位元組順序,後來這個術語被廣泛接納了(摘自《深入理解電腦系統》)。

 

需要特別指出的是,通常所提到的Little Endian和Big Endian僅僅指位元組順序。在硬體設計者的術語中,對於一個位元組內部的bit順序也分Little Endian和Big Endian,但對於程式員而言,這些bit順序的不同是透明的,也就是說,程式員只需要按照邏輯順序來看待和操作位元組內部的bit即可。

 

Endian的不同不僅僅帶來位元組順序的不同,還有更多的問題。如果C程式員在定義一個結構體時,使用了bitwise的域定義,比如:

 

struct foo {

int     a:3;

int     b:7;

int     c:13;

int     d:9;

};

 

這個結構體的一個對象會佔用4個位元組。由於a,b,c,d的類型都是int,所以他們都在以int32為單位的整數上分配bit,另外,由於他們的bit數量正好等於int32的bit數,所以,它們都分配於一個int所佔用的空間。關鍵問題在於這些位元組在這4個位元組內是分配順序是怎麼樣的?

 

對於little endian,其分配順序與邏輯順序是一致的,即在byte[0]的bit[0~2]上分配a,在byte[0]的bit[3,7]以及byte[1]的bit[0,1]上分配b,依次類推。

 

對於big endian,其方案會帶來很大的問題。其分配順序為:

 

位元組物理順序:從低到高;

位元組內bit順序:從高到底;

 

也就是說,big endian在bitwise的分配方案上,從位元組順序到bit順序都反過來了(因為其正向儲存順序為:位元組從高到底,bit從低到高(從程式員的觀點看))。換句話說:big endian的bit分配順序為,按照bit的邏輯順序,從高到底進行分配。

 

 

                        |--------|--------|--------|--------|

Logical Byte Order      | byte 3 | byte 2 | byte 1 | byte 0 |

                        |--------|--------|--------|--------|

Physical Byte Order     | byte 0 | byte 1 | byte 2 | byte 3 |

                        |--------|--------|--------|--------|

Bitwise allocation      |-a-|---b---|------c------|----d----|

 

請注意,並不是硬體平台使用的這種方案,而是C語言編譯器。這是一種荒謬的方案,我想可能是C語言編譯器的早期開發人員希望通過編譯器屏蔽掉big endian和little endian在bitwise allocation上的差異,而都與實體儲存體順序一致。但由於其採用了bit order的反向分配,反而加劇了這種差異,隨後的編譯器為了保持相容,也只好將錯誤延續了下來。

 

基於這種原因,在C語言中直接使用bitwise的方式定義結構體是一種危險的方式,因為這些代碼是平台依賴的。當進行跨平台移植的時候必須重新定義這些結構體。

 

有兩種方式可以消除這種風險:

 

1、使用邏輯移位的方式來操作bit。以上面的例子為例,我們可以這麼做:

 

struct foo {

int value;

};

 

#define SET_A(f,a)     do { (f) |= ((a)&0x7); } while(0)

#define SET_B(f,b)     do { (f) |= (((b)&0x7F)<<3); } while(0)

#define SET_C(f,c)     do { (f) |= (((c)&0x1FFF)<<10); } while(0)

#define SET_D(f,d)     do { (f) |= (((d)&0x1FF)<<23); } while(0)

 

#define GET_A(f)       ((f)&0x7)

#define GET_B(f)       (((f)>>3)&0x7F)

#define GET_C(f)       (((f)>>10)&0x1FFF)

#define GET_D(f)       (((f)>>23)&0x1FF)

 

2、對於big endian,我們可以使用相反的順序來聲明bitwise fields。仍然以上例為例:

 

#if LITTLE_ENDIAN

#define BITWISE(type,a,b,c,d)     type a, b, c, d

#else

#define BITWISE(type,a,b,c,d)     type d, c, b, a

#endif

 

struct foo {

BITWISE(int, a:3, b:7, c:13, d:9);

};

 

對於little endian,邏輯順序與物理順序一致,只需要按照原樣定義;而對於big endian,由於其整體的bit順序恰好與邏輯順序是相反的,所以,我們將順序反過來,使其bit的分配順序與邏輯順序一致即可。

 

來源文件 <http://hi.baidu.com/huoyanliu/blog/item/add5ebdc6f5370aacc116623.html>

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.