大端存儲模式是指字或半字的最高字節(Most Significant Bit,MSB)存放在內存的最低位字節地址上,而字數據的低字節則存放在高地址中。打個比方,有一個字爲0x12345678,這個字由4個字節組成,從高位到低位的次序爲:0x12,0x34,0x56,0x78。若是把這個字存放在以0x00000000起始的內存中,這個字在內存中的實際存放狀況以下表:web
內存地址網絡 |
存儲的數據(Byte)ide |
0x00000000spa |
0x12.net |
0x00000001orm |
0x34blog |
0x00000002ip |
0x56內存 |
0x00000003ci |
0x78 |
0x00000004 |
…… |
大端模式的次序就像是咱們平時書寫的次序,先寫大數,後寫小數。另外,大端存儲次序還普遍運用在TCP/IP協議上,所以又稱爲網絡字節次序。
小端存儲模式是指字或半字的最低位字節(Lowest Significant Bit,LSB)存放在內存的最低位字節地址上,而字數據的高字節則存放在高地址中。還以0x12345678爲例,在小端模式下存儲以下表所示:
內存地址 |
存儲的數據(Byte) |
0x00000000 |
0x78 |
0x00000001 |
0x56 |
0x00000002 |
0x34 |
0x00000003 |
0x12 |
0x00000004 |
…… |
須要注意的幾點是:
(1) 數據在寄存器中都是以大端模式次序存放的。
(2) 對於內存中以小端模式存放的數據。CPU存取數成時,小端和大端之間的轉換是經過硬件實現的,沒有數據加載/存儲的開銷。
例題1:
int main()
{
long long a=1;
long long b=2;
long long c=3;
printf("%d,%d,%d",a,b,c);
return 0;
}
輸出結果是什麼?(32位環境,cpu爲小端模式,全部參數用棧傳遞)
解答:
在32和64上面, long long都是8字節,小端模式是將數據的低位字節存放在內存的低位地址上。printf("%d %d %d\n", a, b, c)依次將c , b, a三個long long型的數據壓入棧中,而後以d%的格式輸出,會依次從a的地址開始輸出3個整型數據(4B)一共是12B,調用printf時參數從右至左壓棧,壓棧順序是c,b,a且地址是連續存放的,小端狀況下從a開始的棧去內存內容以下:
0x 01 00 00 00 00 00 00 00
0x 02 00 00 00 00 00 00 00
0x 03 00 00 00 00 00 00 00
因此連續輸出12個字節的結果就是:1 0 2
知道了大小端模式的概念,但若是讓咱們用C語言寫段代碼判斷一個CPU是大端模式仍是小端模式應當如何作呢 ?
要用C語言簡潔的實現就要用到聯合體(union),簡單的說union就是一種結構,在union中全部的數據成員共用一個存儲空間,在同一時間只能存儲其中的一個數據成員,全部的數據成員具相同的起始地址,相對於基地址的偏移量都爲0;
採用union來判斷,具體代碼以下: