位元組序(大小端)詳解從高低位址和高低位開始理解

2021-07-03 01:44:46 字數 2949 閱讀 7248

原帖: 

一、位元組序定義

位元組序,顧名思義位元組的順序,再多說兩句就是大於乙個位元組型別的資料在記憶體中的存放順序(乙個位元組的資料當然就無需談順序的問題了)。

其實大部分人在實際的開發中都很少會直接和位元組序打交道。唯有在跨平台以及網路程式中位元組序才是乙個應該被考慮的問題。

在所有的介紹位元組序的文章中都會提到位元組序分為兩類: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 檢視輸出結果,判斷大小端位元組序 ...