不同體系結構的CPU,數據在內存中存放的排列順序是不一樣的。
存儲器中對數據的存儲是以字節(Byte)爲基本單位的,因此,字(Word)和半字(Half-Word)在存儲器中就有兩種次序,分別稱爲:大端模式(Big Endian)和小端模式(Little Endian)。
大端存儲模式是指字或半字的最高字節(Most Significant Bit,MSB)存放在內存的最低位字節地址上,而字數據的低字節則存放在高地址中。打個比方,有一個字爲0x12345678,這個字由4個字節組成,從高位到低位的次序爲:0x12,0x34,0x56,0x78。如果把這個字存放在以0x00000000起始的內存中,這個字在內存中的實際存放情況如下表:
內存地址 |
存儲的數據(Byte) |
0x00000000 |
0x12 |
0x00000001 |
0x34 |
0x00000002 |
0x56 |
0x00000003 |
0x78 |
0x00000004 |
…… |
大端模式的次序就像是我們平時書寫的次序,先寫大數,後寫小數。另外,大端存儲次序還廣泛運用在TCP/IP協議上,因此又稱爲網絡字節次序。
小端存儲模式是指字或半字的最低位字節(Lowest Significant Bit,LSB)存放在內存的最低位字節地址上,而字數據的高字節則存放在高地址中。還以0x12345678爲例,在小端模式下存儲如下表所示:
內存地址 |
存儲的數據(Byte) |
0x00000000 |
0x78 |
0x00000001 |
0x56 |
0x00000002 |
0x34 |
0x00000003 |
0x12 |
0x00000004 |
…… |
需要注意的幾點是:
(1) 數據在寄存器中都是以大端模式次序存放的。
(2) 對於內存中以小端模式存放的數據。CPU存取數成時,小端和大端之間的轉換是通過硬件實現的,沒有數據加載/存儲的開銷。
知道了大小端模式的概念,但如果讓我們用C語言寫段代碼判斷一個CPU是大端模式還是小端模式應當如何做呢 ?
要用C語言簡潔的實現就要用到聯合體(union),簡單的說union就是一種結構,在union中所有的數據成員共用一個存儲空間,在同一時間只能存儲其中的一個數據成員,所有的數據成員具相同的起始地址,相對於基地址的偏移量都爲0;
採用union來判斷,具體代碼如下:
int CheckEndian(void)
{
union check
{
int i;
char c;
} Endian;
Endian.i = 1;
return (Endian.c == 1);
}
函數返回0是大端模式,返回1則是小端模式。