大端模式&小端模式、主機序&網絡序、入棧地址高低問題

1、大端模式&小端模式web

所謂的「大端模式」,是指數據的低位(就是權值較小的後面那幾位)保存在內存的高地址中,而數據的高位,保存在內存的低地址中,這樣的存儲模式有點兒相似於把數據看成字符串順序處理:地址由小向大增長,而數據從高位往低位放;網絡

所謂的「小端模式」,是指數據的低位保存在內存的低地址中,而數據的高位保存在內存的高地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低,和咱們的邏輯方法一致。socket

若是將一個32位的整數0x12345678 存放到一個整型變量(int)中,這個整型變量採用大端或者小端模式在內存中的存儲由下表所示。爲簡單起見,本文使用OP0表示一個32位數據的最高字節MSB(Most Significant Byte),使用OP3表示一個32位數據最低字節LSB(Least Significant Byte)。   函數

地址偏移        大端模式       小端模式
0x00           12(OP0)      78(OP3)
0x01           34(OP1)      56(OP2)
0x02           56(OP2)      34(OP1)
0x03           78(OP3)      12(OP0)
測試


小端:較高的有效字節存放在較高的存儲器地址,較低的有效字節存放在較低的存儲器地址。
大端:較高的有效字節存放在較低的存儲器地址,較低的有效字節存放在較高的存儲器地址。

採用大小模式對數據進行存放的主要區別在於在存放的字節順序大端方式將高位存放在低地址,小端方式將高位存放在高地址。採用大端方式進行數據存放符合人類的正常思惟,而採用小端方式進行數據存放利於計算機處理。到目前爲止,採用大端或者小端進行數據存放,其孰優孰劣也沒有定論。 編碼

下面這段代碼能夠用來測試一下你的編譯器是大端模式仍是小端模式: spa

short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址單元
x1=((char*)&x)[1]; //高地址單元
若x0=0x11,則是大端; 若x0=0x22,則是小端......
上面的程序還能夠看出,數據尋址時,用的是低位字節的地址
操作系統

2、主機序&網絡序設計

不一樣的 CPU 有不一樣的字節序類型這些字節序是指整數在內存中保存的順序這個叫作主機序,最多見的有兩種:
一、Little endian :將低序字節存儲在起始地址
二、Big endian :將高序字節存儲在起始地址
orm

網絡字節順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操做系統等無關,從而能夠保證數據在不一樣主機之間傳輸時可以被正確解釋。網絡字節順序採用big endian排序方式。

爲了進行轉換 bsd socket提供了轉換的函數 有下面四個:
htons 把unsigned short類型從主機序轉換到網絡序
htonl 把unsigned long類型從主機序轉換到網絡序
ntohs 把unsigned short類型從網絡序轉換到主機序
ntohl 把unsigned long類型從網絡序轉換到主機序


在使用little endian的系統中,這些函數會把字節序進行轉換
在使用big endian類型的系統中,這些函數會定義成空宏

一樣,在網絡程序開發時,或是跨平臺開發時,也應該注意保證只用一種字節序,否則兩方的解釋不同就會產生BUG。

注:
一、網絡與主機字節轉換函數:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
二、不一樣的CPU上運行不一樣的操做系統,字節序也是不一樣的,參見下表:


處理器             操做系統     字節排序
Alpha                   所有      Little endian
HP-PA                    NT       Little endian
HP-PA                   UNIX     Big endian
Intelx86                所有     Little endian <-----x86系統是小端字節序系統
Motorola680x()          所有    Big endian
MIPS                     NT       Little endian
MIPS                    UNIX    Big endian
PowerPC                  NT     Little endian
PowerPC                 非NT    Big endian   <-----PPC系統是大端字節序系統
RS/6000                 UNIX    Big endian
SPARC                   UNIX    Big endian
IXP1200 ARM核心         所有      Little endian

下面是一個檢驗本機字節序的簡便方法:

//判斷本機的字節序
//返回true表爲小段序。返回false表示爲大段序
bool am_little_endian ()
{
unsigned short i=1;
return (int)*((char *)(&i)) ? true : false;
}
int main()
{
   if(am_little_endian())
{
            printf("本機字節序爲小段序!\n");
}
else
{
          printf("本機字節序爲大段序!\n");
}
        return 0;
}

3、入棧地址高低問題

堆棧是在內存中指定的一段特殊存儲區,存起始單元的地址叫棧底,當前存儲單元地址叫棧頂,堆棧存儲區一旦指定,棧底就固定不變了,而棧頂是隨入棧、出棧操做呈動態。而不一樣機型的堆棧設計,有兩種狀況:一是每入棧一個數,棧頂地址加1,每出棧一個數,棧頂地址減1,即堆棧區是由內存的低地址向高地址。另外一種是每入棧一個數,棧頂地址減1,每出棧一個數,棧頂地址加1,即堆棧區是由內存的高地址向低地址高地址、低地址是相對而言,即相對地址編碼的大小而言。

相關文章
相關標籤/搜索