01低地址-高地址,低字節(jié)-高字節(jié)
一般一個16位(雙字節(jié))的數(shù)據(jù),比如 FF1A (16進制)
那么高位字節(jié)就是FF,低位是1A
如果是32位的數(shù)據(jù),比如 3F68415B
高位字(不是字節(jié))是3F68
低位字是415B
右邊是低位位,左邊是高位
## C語言中的高位字節(jié)和低位字節(jié)是什么意思?
通常從最高有效位開始自左向右書寫一個數(shù)字。在理解有效位這個概念時,可以想象一下你的支票數(shù)額的第一位增加1和最后一位增加1之間的巨大區(qū)別,前者肯定會讓你喜出望外。
計算機內(nèi)存中一個字節(jié)的位相當于二進制數(shù)的位,這意味著最低有效位表示1,倒數(shù)第二個有效位表示2×1或2,倒數(shù)第三個有效位表示2×2×1或4,依此類推。如果用內(nèi)存中的兩個字節(jié)表示一個16位的數(shù),那么其中的一個字節(jié)將存放最低的8位有效位,而另一個字節(jié)將存放最高的8位有效位,見圖。存放最低的8位有效位的字節(jié)被稱為最低有效位字節(jié)或低位字節(jié),而存放最高的8位有效位的字節(jié)被稱為最高有效位字節(jié)或高位字節(jié)。

image.png
## 16位和32位的數(shù)是怎么存儲的?
一個16位的數(shù)占兩個字節(jié)的存儲空間,即高位字節(jié)和低位字節(jié)(見上圖)。如果是在紙上書寫一個16位的數(shù),你總是會把高位字節(jié)寫在前面,而把低位字節(jié)寫在后面。然而,當這個數(shù)被存儲到內(nèi)存中時**,并沒有固定的存儲順序**。
如果用M和L分別表示高位字節(jié)和低位字節(jié),那么可以有兩種方式把這兩個字節(jié)存儲到內(nèi)存中,即M在前L在后或者L在前M在后。把M存儲在前的順序被稱為“正向(forward)”或“高位優(yōu)先順序;把L存儲在前的順序被稱為“逆向”或“低位優(yōu)先”順序。
大多數(shù)計算機按正向順序存儲一個數(shù),Intel CPU按逆向順序存儲一個數(shù),因此,如果試圖將基于Intel CPU的計算機連到其它類型的計算機上,就可能會引起混亂。
一個32位的數(shù)占4個字節(jié)的存儲空間,如果我們按有效位從高到低的順序,分別用Mm,Ml,Lm和Ll表示這4個字節(jié),那么可以有4!(4的階乘,即24)種方式來存儲這些字節(jié)。在過去的這些年中,人們在設(shè)計計算機時,幾乎用遍了這24種方式。然而,時至今天,只有兩種方式是最流行的,一種是(Mm,MI,Lm,LD,也就是高位優(yōu)先順序,另一種是(Ll,Lm,Ml,Mm),也就是低位優(yōu)先順序。和存儲16位的數(shù)一樣,大多數(shù)計算機按高位優(yōu)先順序存儲32位的數(shù),但基于Intel CPU的計算機按低位優(yōu)先順序存儲32位的數(shù)。
02 大端-小端
# Socket相關(guān)知識點
## 網(wǎng)絡(luò)字節(jié)序與主機字節(jié)序
**主機字節(jié)序:**就是我們平常說的大端和小端模式:不同的CPU有不同的字節(jié)序類型,這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序,這個叫做主機序。引用標準的Big-Endian和Little-Endian的定義如下:
a) Little-Endian就是低位字節(jié)排放在內(nèi)存的低地址端,高位字節(jié)排放在內(nèi)存的高地址端。
b) Big-Endian就是高位字節(jié)排放在內(nèi)存的低地址端,低位字節(jié)排放在內(nèi)存的高地址端。
**網(wǎng)絡(luò)字節(jié)序**:4個字節(jié)的32 bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。這種傳輸次序稱作大端字節(jié)序。**由于TCP/IP首部中所有的二進制整數(shù)在網(wǎng)絡(luò)中傳輸時都要求以這種次序,因此它又稱作網(wǎng)絡(luò)字節(jié)序。**字節(jié)序,顧名思義字節(jié)的順序,就是大于一個字節(jié)類型的數(shù)據(jù)在內(nèi)存中的存放順序,一個字節(jié)的數(shù)據(jù)沒有順序的問題了。所以:在將一個地址綁定到socket的時候,請先將主機字節(jié)序轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)序,而不要假定主機字節(jié)序跟網(wǎng)絡(luò)字節(jié)序一樣使用的是Big-Endian。
## 為什么會有大小端模式之分呢?
這是因為在計算機系統(tǒng)中,我們是以字節(jié)為單位的,每個地址單元都對應(yīng)著一個字節(jié),一個字節(jié)為8bit。但是在C語言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對于位數(shù)大于8位的處理器,例如16位或者32位的處理器,由于寄存器寬度大于一個字節(jié),那么必然存在著一個如果將多個字節(jié)安排的問題。因此就導致了大端存儲模式和小端存儲模式。例如一個16bit的short型x,在內(nèi)存中的地址為0x0010,x的值為0x1122,那么0x11為高字節(jié),0x22為低字節(jié)。對于大端模式,就將0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,剛好相反。我們常用的X86結(jié)構(gòu)是小端模式,而KEIL C51則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是大端模式還是小端模式。

image.png
03 Intel - motorola
在定義CAN通信矩陣或制作dbc時,我們需要知道報文的字節(jié)排列順序。字節(jié)的排列順序有2種,一種是Intel的排列順序,另一種是Motorola的排列順序,就跟大小端字節(jié)排序是一樣的。
Intel格式:
Intel格式跟小端格式一樣,低地址代表低字節(jié),高地址代表高字節(jié)。比如一個信號Intel,它的起始位為3,長度為10,在dbc中它的排列順序如下所示:

image.png
要注意其箭頭的增長方向,這樣我們在提取該信號的值為
Intel = (byte0 >> 3) + (byte1 << 5)
其中(byte0 >> 3)為低字節(jié)的值,(byte1 << 5)為高字節(jié)的值。
Motorola格式:
Motorola格式跟大端格式一樣,低地址代表高字節(jié),高地址代表低字節(jié)。與Intel不一樣,Motorola格式有2種表達方式,一種是Motorola_LSB,另一種是Motorola_MSB,但實際上它們代表的數(shù)據(jù)結(jié)構(gòu)是一樣的,只是表達方式不一樣而已,其中Motorola_LSB的起始位是從低字節(jié)開始的,而Motorola_MSB的起始位是從高字節(jié)開始的。在dbc中,只有Motorola_LSB的表達格式,沒有Motorola_MSB的表達格式,比如一個Motorola_LSB的信號MotorolaSignal,其起始位為10,長度為10,在dbc中,其排列順序如下所示:

image.png
要注意其箭頭的增長方向,這樣我們在提取該信號的值為
MotorolaSignal= (byte1 >> 2) + (byte0 << 6)
其中(byte1 >> 2)為低字節(jié)的值,(byte0 << 6)為高字節(jié)的值。
該MotorolaSignal信號用Motorola_MSB表示則為起始位為3,長度為10,但其值的計算方式跟Motorola_LSB是一樣的。
原文鏈接:https://blog.csdn.net/qq_41256212/article/details/95477467
https://www.cnblogs.com/cuijl/p/8005741.html