天天看點

大小端模式 & 位元組序

  大、小端模式的說法,來自喬納森·斯威夫特的小說《格列夫遊記》,在小人國内部分裂成 Big-endian 和 Little-endian 兩派,他們的争論在于一派要求從雞蛋的大頭把雞蛋打破,另一派要求從雞蛋的小頭把雞蛋打破。斯威夫特借以諷刺英國的政黨之争,而計算機工業則借此表示資料儲存順序的分歧。

  大端模式,是指資料的高位元組儲存在記憶體的低位址中,而資料的低位元組儲存在記憶體的高位址中,這樣的存儲模式有點兒類似于把資料當作字元串順序處理:位址由小向大增加,而資料從高位往低位放;這和我們的閱讀習慣一緻。

  記憶方法: 位址的增長順序與值的增長順序相反。

  小端模式,是指資料的高位元組儲存在記憶體的高位址中,而資料的低位元組儲存在記憶體的低位址中,這種存儲模式将位址的高低和資料位權有效地結合起來,高位址部分權值高,低位址部分權值低,和我們的邏輯方法一緻。

  記憶方法: 位址的增長順序與值的增長順序相同。

  那麼,為什麼會有大小端模式之分呢?

  這是因為在計算機系統中,我們是以位元組為機關的,每個位址單元都對應着一個位元組,一個位元組為 8bit。但是在C語言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對于位數大于 8位的處理器,例如16位或者32位的處理器,由于寄存器寬度大于一個位元組,那麼必然存在着一個如何将多個位元組安排的問題。是以就導緻了大端存儲模式和小端存儲模式。例如一個16bit的short型x,在記憶體中的位址為0x0010,x的值為0x1122,那麼0x11為高位元組,0x22為低位元組。對于大端模式,就将0x11放在低位址(即0x0010)中,0x22放在高位址中(即0x0011)中。小端模式,剛好相反。我們常用的X86結構是小端模式,而KEIL C51則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以随時在程式中(在ARM Cortex 系列使用REV、REV16、REVSH指令)進行大小端的切換。

  如此說來,大小端模式就是處理器在記憶體中對多位元組資料進行存取的不同方式。注意兩點:一是處理器,大小端模式是處理器的差異造成的;二是多位元組資料,也就是說隻有處理器操作的資料類型超過一個位元組時才會存在大小端模式的問題,而操作char類型資料是不存在該問題的。

  

  位元組序是指多位元組資料在計算機記憶體中存儲或者網絡傳輸時各位元組的存儲順序。位元組序與大小端模式的概念相似,我們上面所說的就是在計算機記憶體中存儲的位元組順序問題(即主機位元組序),此外還存在網絡傳輸中的位元組順序問題(即網絡位元組序)。

  

  那麼,為什麼會存在網絡位元組序呢?

  我們知道,網絡傳輸上的資料流是位元組流,對于一個多位元組數值,在進行網絡傳輸的時候,就需要考慮先傳遞哪個位元組?也就是說,當接收端收到第一個位元組的時候,它是将這個位元組作為高位還是低位來處理呢?實際上,接收端收到的第一個位元組會被當作高位看待,這就要求發送端發送的第一個位元組應當是高位。而在發送端發送資料時,發送的第一個位元組是該數字在記憶體中起始位址對應的位元組。可見多位元組數值在發送前,在記憶體中數值應該以大端模式存放。