|
端模式(Endian)的這個詞出自JonathanSwift書寫的《格列佛游記》。這本書根據(jù)將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為BigEndian,從尖頭開始將雞蛋敲開的人被歸為LittileEndian。小人國的內(nèi)戰(zhàn)就源于吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開。在計算機(jī)業(yè)Big Endian和LittleEndian也幾乎引起一場戰(zhàn)爭。在計算機(jī)業(yè)界,Endian表示數(shù)據(jù)在存儲器中的存放順序。下文舉例說明在計算機(jī)中大小端模式的區(qū)別。
如果將一個32位的整數(shù)0x12345678存放到一個整型變量(int)中,這個整型變量采用大端或者小端模式在內(nèi)存中的存儲由下表所示。為簡單起見,這里使用OP0表示一個32位數(shù)據(jù)的最高字節(jié)MSB(MostSignificant Byte),使用OP3表示一個32位數(shù)據(jù)最低字節(jié)LSB(Least SignificantByte)。
地址偏移 大端模式 小端模式
0x00 12(OP0) 78(OP3)
0x01 34(OP1) 56(OP2)
0x02 56(OP2) 34(OP1)
0x03 78(OP3) 12(OP0)
如果將一個16位的整數(shù)0x1234存放到一個短整型變量(short)中。這個短整型變量在內(nèi)存中的存儲在大小端模式由下表所示。
地址偏移 大端模式 小端模式
0x00 12(OP0) 34(OP1)
0x01 34(OP1) 12(OP0)
由上表所知,采用大小模式對數(shù)據(jù)進(jìn)行存放的主要區(qū)別在于在存放的字節(jié)順序,大端方式將高位存放在低地址,小端方式將低位存放在低地址。采用大端方式進(jìn)行數(shù)據(jù)存放符合人類的正常思維,而采用小端方式進(jìn)行數(shù)據(jù)存放利于計算機(jī)處理。到目前為止,采用大端或者小端進(jìn)行數(shù)據(jù)存放,其孰優(yōu)孰劣也沒有定論。
有的處理器系統(tǒng)采用了小端方式進(jìn)行數(shù)據(jù)存放,如Intel的奔騰。有的處理器系統(tǒng)采用了大端方式進(jìn)行數(shù)據(jù)存放,如IBM半導(dǎo)體和Freescale的PowerPC處理器。不僅對于處理器,一些外設(shè)的設(shè)計中也存在著使用大端或者小端進(jìn)行數(shù)據(jù)存放的選擇。
因此在一個處理器系統(tǒng)中,有可能存在大端和小端模式同時存在的現(xiàn)象。這一現(xiàn)象為系統(tǒng)的軟硬件設(shè)計帶來了不小的麻煩,這要求系統(tǒng)設(shè)計工程師,必須深入理解大端和小端模式的差別。大端與小端模式的差別體現(xiàn)在一個處理器的寄存器,指令集,系統(tǒng)總線等各個層次中。判斷大端小端
inti=1;
char*p=(char*)&i;
if(*p==1)
printf("1");
else
printf("2");
大小端存儲問題,如果小端方式中(i占至少兩個字節(jié)的長度)則i所分配的內(nèi)存最小地址那個字節(jié)中就存著1,其他字節(jié)是0.大端的話則1在i的最高地址字節(jié)處存放,char是一個字節(jié),所以強(qiáng)制將char型量p指向i則p指向的一定是i的最低地址,那么就可以判斷p中的值是不是1來確定是不是小端。
請寫一個C函數(shù),若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1
解答:
int checkCPU( )
{
{
unionw
{
int a;
char b;
}c;
c.a= 1;
return(c.b==1);
}
}
剖析:
嵌入式系統(tǒng)開發(fā)者應(yīng)該對Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU對操作數(shù)的存放方式是從低字節(jié)到高字節(jié),而Big-endian模式對操作數(shù)的存放方式是從高字節(jié)到低字節(jié)。例如,16bit寬的數(shù)0x1234在Little-endian模式CPU內(nèi)存中的存放方式(假設(shè)從地址0x4000開始存放)為:
內(nèi)存地址
| 0x4000
| 0x4001
| 存放內(nèi)容
| 0x34
| 0x12
|
而在Big-endian模式CPU內(nèi)存中的存放方式則為:
內(nèi)存地址
| 0x4000
| 0x4001
| 存放內(nèi)容
| 0x12
| 0x34
|
32bit寬的數(shù)0x12345678在Little-endian模式CPU內(nèi)存中的存放方式(假設(shè)從地址0x4000開始存放)為:
內(nèi)存地址
| 0x4000
| 0x4001
| 0x4002
| 0x4003
| 存放內(nèi)容
| 0x78
| 0x56
| 0x34
| 0x12
|
而在Big-endian模式CPU內(nèi)存中的存放方式則為:
內(nèi)存地址
| 0x4000
| 0x4001
| 0x4002
| 0x4003
| 存放內(nèi)容
| 0x12
| 0x34
| 0x56
| 0x78
|
聯(lián)合體union的存放順序是所有成員都從低地址開始存放,面試者的解答利用該特性,輕松地獲得了CPU對內(nèi)存采用Little-endian還是Big-endian模式讀寫。
|
|