資源描述:
《字節(jié)序字節(jié)對(duì)齊的理解》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、1、前言作為一名C/C++程序員,字節(jié)是我們天天都要與之打交道的一個(gè)東西。我們和它熟稔到幾乎已經(jīng)忘記了它的存在??墒?,它自己是不甘寂寞的,或遲或早地,總會(huì)在某些時(shí)候探出頭來(lái)張望,然后給你一個(gè)腿兒絆。其實(shí),只要你真正了解了它的底細(xì),你就會(huì)暢行無(wú)阻。在本文中,我們將首先簡(jiǎn)要了解一下字節(jié)的概念,然后著重了解一下字節(jié)序問(wèn)題和字節(jié)對(duì)齊問(wèn)題。2、什么是字節(jié)我們知道,二進(jìn)制計(jì)算機(jī)(也就是我們目前接觸到的幾乎所有的計(jì)算機(jī))的最小數(shù)據(jù)單位是位(bit)。一位數(shù)據(jù)只能夠表示兩種含義(需要說(shuō)明,盡管我們通常把單個(gè)位表示的兩種含義選擇為相互對(duì)立的含義,但這并不是必
2、然的,例如你可以認(rèn)為1代表5個(gè)人,0代表8個(gè)人),對(duì)于絕大多數(shù)的計(jì)算要求,單個(gè)位顯然不能滿足。因此,我們通常都會(huì)使用一連串的位,我們可以稱(chēng)之為位串(bitstring,請(qǐng)愛(ài)好質(zhì)疑的的朋友注意,此術(shù)語(yǔ)非我杜撰)。由于種種原因,計(jì)算機(jī)系統(tǒng)都不會(huì)讓你使用任意長(zhǎng)度的位串,而是使用某個(gè)特定長(zhǎng)度的位串。一些常見(jiàn)的位串長(zhǎng)度形式具有約定好的名稱(chēng),如,半字節(jié)(nibble,貌似用的不多)代表四個(gè)位的組合,字節(jié)(byte,主角出場(chǎng)?。┐?個(gè)位的組合。再多的還有,字(word)、雙字(Doubleword,通常簡(jiǎn)寫(xiě)為Dword)、四字(Quadword,經(jīng)常簡(jiǎn)
3、寫(xiě)為Qword)、十字節(jié)(Tenbyte,也簡(jiǎn)寫(xiě)為T(mén)byte)。在這些里面,字(word)有時(shí)表示不同的含義。在Intel體系里,word表示一個(gè)16位的數(shù)值,它是固定大小的。而在另外一些場(chǎng)合,word表示了CPU一次可處理的數(shù)據(jù)的位數(shù),表示一個(gè)符合CPU字長(zhǎng)(word-length)的數(shù)目的位串。事實(shí)上我們接觸較多的ARM體系中,word就有不同的含義,它表示一個(gè)32位的數(shù)據(jù)(與機(jī)器字長(zhǎng)相同),對(duì)于16位大小的數(shù)據(jù),ARM使用了另外的一個(gè)術(shù)語(yǔ),叫作半字(half-word),請(qǐng)大家在文檔閱讀時(shí)加以注意。另外,Qword也是Intel體系中
4、的術(shù)語(yǔ),其他的體系中可能并不使用。在本文中,我們按照Intel的慣例來(lái)使用字或者word這一術(shù)語(yǔ)。一個(gè)字節(jié)中共有8個(gè)數(shù)據(jù)位,有時(shí)需要用圖表逐位表述各個(gè)位。習(xí)慣上,我們按照下面的圖來(lái)排列各個(gè)位的順序,即,按照從右到左的順序,依次為最低位(從第0位開(kāi)始)到最高位(對(duì)于字節(jié),則是第7位):字節(jié)是大多數(shù)現(xiàn)代計(jì)算機(jī)的最小存儲(chǔ)單元,但這并不代表它是計(jì)算機(jī)可以最高效地處理的數(shù)據(jù)單位。一般的來(lái)說(shuō),計(jì)算機(jī)可以最高效地處理的數(shù)據(jù)大小,應(yīng)該與其字長(zhǎng)相同。在目前來(lái)講,桌面平臺(tái)的處理器字長(zhǎng)正處于從32位向64位過(guò)渡的時(shí)期,嵌入式設(shè)備的基本穩(wěn)定在32位,而在某些專(zhuān)業(yè)領(lǐng)
5、域(如高端顯卡),處理器字長(zhǎng)早已經(jīng)達(dá)到了64位乃至更多的128位。3、字節(jié)序問(wèn)題的由來(lái)對(duì)于字、雙字這些多于一個(gè)字節(jié)的數(shù)據(jù),如果把它們放置到內(nèi)存中的某個(gè)位置上,可以看出,我們還可以將之看作是字節(jié)的序列。一個(gè)字是兩個(gè)字節(jié),雙字則是四個(gè)字節(jié)。假設(shè)有以下數(shù)據(jù):0x12345678、0x9abcdef0。在此處,我使用了我們最習(xí)慣的十六進(jìn)制表示法,并給出了兩個(gè)雙字的值。按照慣例,我把雙字的左側(cè)視為高端,而把右側(cè)視為低端。把它們順序放置在起始地址為0的內(nèi)存中,如下圖所示:由圖示可知,0x9abcdef的相應(yīng)地址為0x04。現(xiàn)在,問(wèn)題來(lái)了,如果有一個(gè)內(nèi)存
6、操作,要從地址0x06處讀取一個(gè)字,得到的結(jié)果是多少呢?答案是:不一定。這里的本質(zhì)問(wèn)題在于,如何把多字節(jié)的對(duì)象存儲(chǔ)到內(nèi)存中去呢?即使使用最正常的思維去考慮這個(gè)問(wèn)題,你也會(huì)發(fā)現(xiàn)有兩種方法。第一種方法是,把最低端的字節(jié)放到指定的起始位置(即基地址處),然后按照從低到高的字節(jié)順序把其余字節(jié)依次放入,如下圖a;另一種方法非常類(lèi)似,但是對(duì)高端字節(jié)和低端字節(jié)的處理順序正好相反,如下圖b(我確信你還可以想出其他的方法,但是除二字節(jié)的情況外,必然會(huì)打破字節(jié)排列順序的一致性,我視之為反常規(guī)思維的產(chǎn)物,此處暫不考慮)。圖a圖b在很久之前,哪一種存儲(chǔ)方式更為合理
7、曾經(jīng)有過(guò)爭(zhēng)論。到今天,爭(zhēng)論的結(jié)果已經(jīng)無(wú)關(guān)緊要了,緊要的是以下事實(shí):這兩種存儲(chǔ)方式都被應(yīng)用到了現(xiàn)實(shí)的計(jì)算機(jī)系統(tǒng)中。上圖a中的排列方式為Intel所采用并大行其道,而圖b的排列方式則被大多數(shù)的其他平臺(tái)采用(如最近被蘋(píng)果公司徹底拋棄的PowerPC),因此上,我們不能稱(chēng)之為罕見(jiàn)的用法。之所以造成事實(shí)上的不經(jīng)常見(jiàn)到,其原因正如我今天中午所得到的消息:Intel的CPU占整個(gè)市場(chǎng)份額的80%以上。這兩種排列方式通常用小端(littleendian)和大端(bigendian)來(lái)稱(chēng)謂。這兩個(gè)奇怪的名字據(jù)說(shuō)來(lái)源于童話《格列佛游記》,其中小人國(guó)里的公民為了
8、雞蛋到底是應(yīng)該從小的一頭打開(kāi)還是大的一頭打開(kāi)而大起爭(zhēng)執(zhí)。Intel的方式對(duì)應(yīng)于“小端”,順便說(shuō)一句,大端的方式也有一個(gè)大公司的名字作為其代表,即最近開(kāi)始沒(méi)落的Motorola。如