位元組序(endianness)
/ EN-dee-uhn-ness /
單一位元組就是單一位元組,但一個需要好幾個位元組的數字——一個 32 位元整數需要四個——引出了一個沒有唯一正確答案的問題:那些位元組在記憶體裡以什麼「順序」排列?你是把最高有效位元組擺在前面(像我們寫數字那樣,千在個之前),還是把最低有效位元組擺在前面?這個位元組順序的選擇叫做位元組序,而機器們對此確實意見不一。
大端序把最高有效位元組存在「最低」位址——「大端在前」,符合人類的閱讀順序。小端序把最低有效位元組存在前面,所以位元組看起來與你寫數字的方式相反。以 32 位元值 0x12345678 為例。在大端序機器上,記憶體中由低位址往上的四個位元組是 12 34 56 78。在小端序機器上是 78 56 34 12。數字相同;只是儲存順序不同。這名字俏皮地來自《格列佛遊記》,書中兩派為了該從水煮蛋的哪一端敲開而開戰。
只要你待在同一台機器上以正常方式讀值,位元組序就是隱形的——CPU 會一致地處理它自己的順序。但位元組一跨越邊界,它就變得非常顯眼:存成二進位檔、透過網路傳送資料,或在除錯器裡讀記憶體時。大多數桌機和行動 CPU(x86 和多數 ARM 設定)是小端序,而網路協定統一採用大端序,稱為「網路位元組序」——這正是為什麼程式碼用 htonl() 和 ntohl() 這類函式在收發時轉換整數。弄錯位元組序,1 就會變成 16777216;尊重它,位元組在哪裡都意味著同一件事。
值 0x12345678 在記憶體裡:大端序存成位元組 12 34 56 78(低位址在前);小端序存成 78 56 34 12。把其中一個當成另一個來讀,會把 0x12345678 變成 0x78563412。
相同的數字,相反的位元組順序;網路序是大端序。
位元組序關乎整個「位元組」的順序,而非一個位元組「內」位元的順序(一個位元組的各位元無法個別定址)。它只在多位元組的值跨越機器、檔案或網路時才要緊——在同一個執行中的程式內它保持一致。