理解字節序---大端小端

本篇將以what,why,how三個維度講述字節序

what

字節序,字面理解可知是字節(Byte)的順序,是計算機科學針對多字節結構(變量或者文件等)的一種約定,目前分爲大端字節序小端字節序

以一個 uint32_t 的4字節類型爲例,在該類型的變量中存入0x12345678,從變量的角度來看,0x12爲變量的高字節,0x78爲變量的低字節。

當變量的  字節存放在內存的  地址,變量的  字節存放在內存的 低 地址時,爲小端字節序,如下圖:

 

當變量的  字節存放在內存的  地址,變量的  字節存放在內存的  地址時,爲大端字節序,如下圖:

 

why

定義只是約定,當然可以直接記憶,但是爲什麼要這麼約定?爲什麼要分成兩種字節序?有什麼好處?

兩種字節序針對兩類對象,大端字節序 面向的是 人類小端字節序 面向的是 計算機

大端字節序符合人類閱讀的習慣,對字節流的處理也是按照閱讀習慣來定義,這樣能減少人類的處理負擔,因此如網絡字節序用的就是大端字節序,當網絡socket傳輸一個多位數時,按照閱讀習慣,接收到的是高字節數,因此直接左移8位相加。

小端字節序符合計算機處理的順序

        1.計算機讀取數據不關心格式,僅按照內存地址順序讀取

        2.計算機處理數據從數據低位開始處理,這個也是計算機設計定義的,因此我們需要把變量低地址的數據主動放到內存低地址處,這樣計算機取到數據處理纔是我們所期望的從低地址開始。如累加操作時,個位相加,進位置位CF,再做十位相加,依次進行累加最終得到結果。

綜上,大端字節序面向人類爲了簡化思維,小端字節序面向計算機爲了加快處理速度。

 

how

如何判別計算機是大端字節序還是小端字節序?

可以簡單的用一段C語言程序做判斷

#include <cstdio>
#include <cstdint>

int main()
{
	uint32_t test_code = 0x12345678;
	uint8_t* first = (uint8_t*)&test_code;  //指針指向變量的內存首字節

	printf("first address value is %x,is %s\n", 
			*first, *first == 0x12 ? "Big Endian" : "Little Endian");
	return 0;
}

可以看到輸出爲

first指針指向了變量test_code的內存首地址(內存低地址),取出的結果爲0x78(變量低地址),由上文定義可知爲小端序

 

除了直接查看輸出,我們還能通過查看內存方式自己看看存儲的情況,這裏使用ollyDbg調試上述程序debug模式輸出的exe文件,使用ollyDbg打開該exe文件:

右鍵搜索程序中所有的字符串,這裏主要要找printf中的字符串,因爲是簡單程序沒有加密,很容易能夠找到調用的地方:

直接查看該變量地址的dump

與程序輸出一直,低地址存放着0x78,高地址存放着0x12,因此爲小端序。

 

其實計算機並不一定都是小端序,小端序只是計算機的默認字節序,如果需要更改,可以設置相應的控制寄存器進行設置,達到更改字節序的目的,始終記得字節序只是一種約定。

 
發佈了13 篇原創文章 · 獲贊 7 · 訪問量 6062
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章