大端模式小端模式、主机序网络序、入栈地址高低问题
所謂的“大端模式”,是指數(shù)據(jù)的低位(就是權值較小的后面那幾位)保存在內存的高地址中,而數(shù)據(jù)的高位,保存在內存的低地址中,這樣的存儲模式有點兒類似于把數(shù)據(jù)當作字符串順序處理:地址由小向大增加,而數(shù)據(jù)從高位往低位放;
所謂的“小端模式”,是指數(shù)據(jù)的低位保存在內存的低地址中,而數(shù)據(jù)的高位保存在內存的高地址中,這種存儲模式將地址的高低和數(shù)據(jù)位權有效地結合起來,高地址部分權值高,低地址部分權值低,和我們的邏輯方法一致。
如果將一個32位的整數(shù)0x12345678 存放到一個整型變量(int)中,這個整型變量采用大端或者小端模式在內存中的存儲由下表所示。為簡單起見,本文使用OP0表示一個32位數(shù)據(jù)的最高字節(jié)MSB(Most Significant Byte),使用OP3表示一個32位數(shù)據(jù)最低字節(jié)LSB(Least Significant Byte)。??
地址偏移??????? 大端模式?????? 小端模式?
0x00?????????? 12(OP0)????? 78(OP3)?
0x01?????????? 34(OP1)????? 56(OP2)?
0x02?????????? 56(OP2)????? 34(OP1)?
0x03?????????? 78(OP3)????? 12(OP0)
小端:較高的有效字節(jié)存放在較高的存儲器地址,較低的有效字節(jié)存放在較低的存儲器地址。
大端:較高的有效字節(jié)存放在較低的存儲器地址,較低的有效字節(jié)存放在較高的存儲器地址。
采用大小模式對數(shù)據(jù)進行存放的主要區(qū)別在于在存放的字節(jié)順序,大端方式將高位存放在低地址,小端方式將高位存放在高地址。采用大端方式進行數(shù)據(jù)存放符合人類的正常思維,而采用小端方式進行數(shù)據(jù)存放利于計算機處理。到目前為止,采用大端或者小端進行數(shù)據(jù)存放,其孰優(yōu)孰劣也沒有定論。
下面這段代碼可以用來測試一下你的編譯器是大端模式還是小端模式:
short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址單元
x1=((char*)&x)[1]; //高地址單元
若x0=0x11,則是大端; 若x0=0x22,則是小端......
上面的程序還可以看出,數(shù)據(jù)尋址時,用的是低位字節(jié)的地址
二、主機序&網(wǎng)絡序
不同的 CPU 有不同的字節(jié)序類型這些字節(jié)序是指整數(shù)在內存中保存的順序這個叫做主機序,最常見的有兩種:?
1、Little endian :將低序字節(jié)存儲在起始地址?
2、Big endian :將高序字節(jié)存儲在起始地址
網(wǎng)絡字節(jié)順序是TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無關,從而可以保證數(shù)據(jù)在不同主機之間傳輸時能夠被正確解釋。網(wǎng)絡字節(jié)順序采用big endian排序方式。
為了進行轉換 bsd socket提供了轉換的函數(shù) 有下面四個:
htons 把unsigned short類型從主機序轉換到網(wǎng)絡序
htonl 把unsigned long類型從主機序轉換到網(wǎng)絡序
ntohs 把unsigned short類型從網(wǎng)絡序轉換到主機序
ntohl 把unsigned long類型從網(wǎng)絡序轉換到主機序
在使用little endian的系統(tǒng)中,這些函數(shù)會把字節(jié)序進行轉換?
在使用big endian類型的系統(tǒng)中,這些函數(shù)會定義成空宏
同樣,在網(wǎng)絡程序開發(fā)時,或是跨平臺開發(fā)時,也應該注意保證只用一種字節(jié)序,不然兩方的解釋不一樣就會產(chǎn)生BUG。
注:
1、網(wǎng)絡與主機字節(jié)轉換函數(shù):htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上運行不同的操作系統(tǒng),字節(jié)序也是不同的,參見下表:
處理器???????????? 操作系統(tǒng)???? 字節(jié)排序
Alpha?????????????????? 全部????? Little endian
HP-PA??????????????????? NT?????? Little endian
HP-PA?????????????????? UNIX???? Big endian
Intelx86??????????????? 全部???? Little endian <-----x86系統(tǒng)是小端字節(jié)序系統(tǒng)
Motorola680x()????????? 全部??? Big endian
MIPS???????????????????? NT?????? Little endian
MIPS??????????????????? UNIX??? Big endian
PowerPC????????????????? NT???? Little endian
PowerPC???????????????? 非NT??? Big endian?? <-----PPC系統(tǒng)是大端字節(jié)序系統(tǒng)
RS/6000???????????????? UNIX??? Big endian
SPARC?????????????????? UNIX??? Big endian
IXP1200 ARM核心???????? 全部????? Little endian
?
下面是一個檢驗本機字節(jié)序的簡便方法:
//判斷本機的字節(jié)序
//返回true表為小段序。返回false表示為大段序
bool am_little_endian ()
{
unsigned short i=1;
return (int)*((char *)(&i)) ? true : false;
}
int main()
{
?? if(am_little_endian())
{
???????? ?? printf("本機字節(jié)序為小段序!\n");
}
else
{
????????? printf("本機字節(jié)序為大段序!\n");
}
??????? return 0;
}
三、入棧地址高低問題
堆棧是在內存中指定的一段特殊存儲區(qū),存起始單元的地址叫棧底,當前存儲單元地址叫棧頂,堆棧存儲區(qū)一旦指定,棧底就固定不變了,而棧頂是隨入棧、出棧操作呈動態(tài)。而不同機型的堆棧設計,有兩種情況:一是每入棧一個數(shù),棧頂?shù)刂芳?,每出棧一個數(shù),棧頂?shù)刂窚p1,即堆棧區(qū)是由內存的低地址向高地址。另一種是每入棧一個數(shù),棧頂?shù)刂窚p1,每出棧一個數(shù),棧頂?shù)刂芳?,即堆棧區(qū)是由內存的高地址向低地址。高地址、低地址是相對而言,即相對地址編碼的大小而言。
轉載于:https://www.cnblogs.com/ablogia/p/3266321.html
總結
以上是生活随笔為你收集整理的大端模式小端模式、主机序网络序、入栈地址高低问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JUL
- 下一篇: lols11剑姬怎么出装 出装顺序