位元組序/端序(endianness)
/ EN-dee-an-ness /
當一個值大於一個位元組時——比方說一個 4 位元組整數——電腦必須以某種順序把它的位元組存進記憶體,而有兩種合理的選擇。端序就是一台機器挑了哪一種順序。這名字取自《格列佛遊記》的玩笑,書中兩派為了水煮蛋該從大端還是小端敲開而開戰——為一個其實無所謂的差異而爭,只不過在這裡兩種做法都存在,你必須知道自己面對的是哪一種。
拿 4 位元組的十六進位值 0x12345678 為例。在大端(big-endian)順序裡,最高有效位元組(0x12)先存、放在最低位址,從左讀到右就像我們寫數字:12 34 56 78。在小端(little-endian)順序裡,最低有效位元組(0x78)先存,所以位元組在記憶體裡看起來是反過來的:78 56 34 12。大端對人類感覺自然,也是網路協定的傳統順序(因此稱「網路位元組序」);小端則是多數桌機與筆電處理器、包括 x86 家族,內部使用的順序。在單一機器內部這完全看不見——處理器會正確讀回自己的位元組,所以程式從不必為此操心。
端序只在邊界處咬人:當位元組在不同端序的機器間穿越,或被寫進檔案、經網路送出後再被另一系統讀取時。如果一台小端機器送出一個整數的原始位元組,而一台大端機器天真地讀它,0x12345678 就變成 0x78563412——一個錯得離譜的數。這就是為什麼檔案格式與網路協定會指定固定的位元組序,也是為什麼可攜的程式會明確地與它互相轉換。誠實的總結:端序在一致的單一機器內部從不重要,而在資料離開它的那一刻永遠重要。
32 位元值 0x12345678 存在某位址:大端記憶體裝 12 34 56 78,小端裝 78 56 34 12。在端序不合的機器間不經轉換就傳原始位元組,這個數會悄悄變錯。
大端先存高位元組;小端先存低位元組。
端序在單一機器內看不見,只在位元組跨入檔案、網路或順序不同的機器時咬人。網路協定固定了位元組序,所以可攜的程式必須明確轉換。