大小端以及網路序的區別

2021-09-19 13:55:29 字數 2653 閱讀 8699

前言:

在處理網路通訊資料時,除了按照協議的資料解析和打包,還會涉及到非單位元組資料(16位或者32位)在記憶體中的儲存方式,也就是所謂的大小端問題。

1 什麼是大/小端?小端模式,是指資料的高位元組儲存在記憶體的高位址中,而資料的低位元組儲存在記憶體的低位址中,這種儲存模式將位址的高低和資料位權有效地結合起來,高位址部分權值高,低位址部分權值低。

2 測試方法

在進行測試之前,先思考以下幾個問題:

(1)資料的高低位元組很好理解,那記憶體的高低位址如何區分?

(2)在函式中定義多個區域性陣列變數,其陣列的首位址是遞減還是遞增?單個陣列內的元素的位址遞減還是遞增?棧區的生長方式是?

(3)如何使用聯合體union來測試記憶體模式為大端還是小端?

(4)使用memcpy(dest,sour,length)是否需要注意大小端?

測試硬體平台:stm32f767ni

測試**:

void fun_test()

; union test_u test; //

test.value32 = 0x12345678;

memcpy(&msgbuffer3[0],&test.value32,sizeof(test.value32)); //msgbuffer3中的4個值是12/34/56/78怎樣的順序?

/* 以下的printf 將揭曉答案 */

printf("msgbuffer3[0] value: %x \n",msgbuffer3[0]); //輸出結果為78

printf("msgbuffer3[1] value: %x \n",msgbuffer3[1]); //輸出結果為56

printf("msgbuffer3[2] value: %x \n",msgbuffer3[2]); //輸出結果為34

printf("msgbuffer3[3] value: %x \n",msgbuffer3[3]); //輸出結果為12,這說明高位元組存放在陣列的高偏移中,那高偏移的位址是高位址嗎?請看下面

printf("msgbuffer[0] addr: %x \n",&msgbuffer[0]); //輸出結果為0x20056980

printf("msgbuffer[4] addr: %x \n",&msgbuffer[4]); //輸出結果為0x20056984

printf("msgbuffer[20] addr: %x \n",&msgbuffer[20]);//輸出結果為0x20056994,這說明陣列內的高偏移的位址就是高位址

/* 重要 */

printf("msgbuffer1[0] addr: %x \n",&msgbuffer1[0]);//輸出結果為0x20056960(小於0x20056980),這說明先後定義的陣列的首位址是遞減的,這就說明了在函式中定義的區域性變數是存放在棧區的,生長方式為向下生長。

printf("msgbuffer1[4] addr: %x \n",&msgbuffer1[4]);//輸出結果為0x20056964

printf("msgbuffer1[20] addr: %x \n",&msgbuffer1[20]);//輸出結果為0x20056974

printf("test addr: %dx \n",&test);

printf("test.value8[0] addr: %x \n",&test.value8[0]);//輸出結果為0x20056958

printf("test.value8[1] addr: %x \n",&test.value8[1]);//輸出結果為0x20056959

printf("test.value8[2] addr: %x \n",&test.value8[2]);//輸出結果為0x2005695a

printf("test.value8[3] addr: %x \n",&test.value8[3]);//輸出結果為0x2005695b

printf("test.value8[0] value: %x \n",test.value8[0]);//輸出結果為78

printf("test.value8[1] value: %x \n",test.value8[1]);//輸出結果為56

printf("test.value8[2] value: %x \n",test.value8[2]);//輸出結果為34

printf("test.value8[3] value: %x \n",test.value8[3]);//輸出結果為12,高位址存放高位元組,聯合體說明該平台為小端模式

}

測試結果:

3 網路序

在網路或者串列埠傳輸時,一般定義先到的是高位元組,後到的為低位元組。在接受資料時,陣列buffer[0]為高位元組,但是buffer[0]又是低位址,也就是低位址存放高位元組,這說明所謂的網路序,其實就是大端模式。

4 總結

當通訊雙方的儲存方式不一樣時,在傳送打包/接收解析時均要注意大小端之間的轉換,否則資料就會出現錯亂。

網路位元組序以及大小端

記憶體中的多位元組資料相對於記憶體位址有大端和小段之分,磁碟檔案中的多位元組資料相對於檔案中的偏移位址也有大端和小端之分,網路資料流同樣有大端小端之分,那麼如何定義網路資料流的位址呢?傳送主機通常將傳送快取區中的資料按記憶體位址從低到高的順序發出,接收主機把從網路上接到的位元組依次儲存在接受緩衝區中...

socket網路位元組序以及大端序小端序

不同cpu中,4位元組整數1在記憶體空間的儲存方式是不同的。4位元組整數1可用2進製表示如下 00000000 00000000 00000000 00000001 有些cpu以上面的順序儲存到記憶體,另外一些cpu則以倒序儲存,如下所示 00000001 00000000 00000000 000...

大小端模式的區別

最近在學習usb,在看keil c51 的時候發現從pc機接收的usb資料在keil c51環境裡要交換高低位元組,這是因為keil的資料結構是大端模式,對於大端模式不是很清楚後來網上搜尋發現有一篇文章介紹的比較詳細,不敢獨享貼出來大家學習。所謂的大端模式,是指資料的低位 就是權值較小的後面那幾位 ...