原帖:
一、位元組序定義
位元組序,顧名思義位元組的順序,再多說兩句就是大於乙個位元組型別的資料在記憶體中的存放順序(乙個位元組的資料當然就無需談順序的問題了)。
其實大部分人在實際的開發中都很少會直接和位元組序打交道。唯有在跨平台以及網路程式中位元組序才是乙個應該被考慮的問題。
在所有的介紹位元組序的文章中都會提到位元組序分為兩類:big-endian和little-endian。引用標準的big-endian和little-endian的定義如下:
a) little-endian就是低位位元組排放在記憶體的低位址端,高位位元組排放在記憶體的高位址端。
b) big-endian就是高位位元組排放在記憶體的低位址端,低位位元組排放在記憶體的高位址端。
c) 網路位元組序:4個位元組的32 bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然後16~23bit,最後是24~31bit。這種傳輸次序稱作大端位元組序。由於 tcp/ip首部中所有的二進位制整數在網路中傳輸時都要求以這種次序,因此它又稱作網路位元組序。比如,乙太網頭部中2位元組的「乙太網幀型別」,表示後面資料的型別。對於arp請求或應答的乙太網幀型別來說,在網路傳輸時,傳送的順序是0x08,0x06。在記憶體中的映象如下圖所示:
棧底 (高位址)
---------------
0x06 -- 低位
0x08 -- 高位
---------------
棧頂 (低位址)
該字段的值為0x0806。按照大端方式存放在記憶體中。
二、高/低位址與高低位元組
首先我們要知道我們c程式映像中記憶體的空間布局情況:在《c專家程式設計》中或者《unix環境高階程式設計》中有關於記憶體空間布局情況的說明,大致如下圖:
----------------------- 最高記憶體位址 0xffffffff
| 棧底
.. 棧.棧頂
-----------------------||
\|/
null (空洞)
/|\||
-----------------------
堆-----------------------
未初始化的資料
----------------(統稱資料段)
初始化的資料
-----------------------
正文段(**段)
----------------------- 最低記憶體位址 0x00000000
以上圖為例如果我們在棧上分配乙個unsigned char buf[4],那麼這個陣列變數在棧上是如何布局的呢[注1]?看下圖:
棧底 (高位址)
----------
buf[3]
buf[2]
buf[1]
buf[0]
----------
棧頂 (低位址)
現在我們弄清了高低位址,接著來弄清高/低位元組,如果我們有乙個32位無符號整型0x12345678(呵呵,恰好是把上面的那4個位元組buf看成乙個整型),那麼高位是什麼,低位又是什麼呢?其實很簡單。在十進位制中我們都說靠左邊的是高位,靠右邊的是低位,在其他進製也是如此。就拿 0x12345678來說,從高位到低位的位元組依次是0x12、0x34、0x56和0x78。
高低位址和高低位元組都弄清了。我們再來回顧一下big-endian和little-endian的定義,並用圖示說明兩種位元組序:
以unsigned int value = 0x12345678為例,分別看看在兩種位元組序下其儲存情況,我們可以用unsigned char buf[4]來表示value:
big-endian: 低位址存放高位,如下圖:
棧底 (高位址)
---------------
buf[3] (0x78) -- 低位
buf[2] (0x56)
buf[1] (0x34)
buf[0] (0x12) -- 高位
---------------
棧頂 (低位址)
little-endian: 低位址存放低位,如下圖:
棧底 (高位址)
---------------
buf[3] (0x12) -- 高位
buf[2] (0x34)
buf[1] (0x56)
buf[0] (0x78) -- 低位
---------------
棧頂 (低位址)
在現有的平台上intel的x86採用的是little-endian,而像sun的sparc採用的就是big-endian。
三、例子
嵌入式系統開發者應該對little-endian和big-endian模式非常了解。採用little-endian模式的cpu對運算元的存放方式是從低位元組到高位元組,而big-endian模式對運算元的存放方式是從高位元組到低位元組。
例如,16bit寬的數0x1234在little-endian模式cpu記憶體中的存放方式(假設從位址0x4000開始存放)為:
記憶體位址 存放內容
0x4001 0x12
0x4000 0x34
而在big-endian模式cpu記憶體中的存放方式則為:
記憶體位址 存放內容
0x4001 0x34
0x4000 0x12
32bit寬的數0x12345678在little-endian模式cpu記憶體中的存放方式(假設從位址0x4000開始存放)為:
記憶體位址 存放內容
0x4003 0x12
0x4002 0x34
0x4001 0x56
0x4000 0x78
而在big-endian模式cpu記憶體中的存放方式則為:
記憶體位址 存放內容
0x4003 0x78
0x4002 0x56
0x4001 0x34
0x4000 0x12
位元組序(大小端)詳解從高低位址和高低位開始理解
一 位元組序定義 位元組序,顧名思義位元組的順序,再多說兩句就是大於乙個位元組型別的資料在記憶體中的存放順序 乙個位元組的資料當然就無需談順序的問題了 其實大部分人在實際的開發中都很少會直接和位元組序打交道。唯有在跨平台以及網路程式中位元組序才是乙個應該被考慮的問題。在所有的介紹位元組序的文章中都會...
大小端詳解
前言 本篇文章介紹資料儲存的大小端模式,大小端模式起源於吃雞蛋的典故。首先,我們看一下資料在記憶體是怎麼儲存的 從上邊我們可以看出a b在計算機中儲存的是補碼,但是順序卻倒著的,這實際上就是小端儲存 大端儲存模式 是指資料的低位位元組序儲存在記憶體的高位址中,而資料的高位位元組序儲存在記憶體的低位址...
大小端位元組序
1.大端和小端問題 大小端位元組序與硬體有關 intel x86 都是小端位元組序 總結 大端是 按照正常我們書寫的順序來儲存的 小端是 按照我們書寫順序相反的 實現 include int main putchar n printf x n a return 0 檢視輸出結果,判斷大小端位元組序 ...