字節(jié)序、字節(jié)對(duì)齊的理解.docx_第1頁(yè)
字節(jié)序、字節(jié)對(duì)齊的理解.docx_第2頁(yè)
字節(jié)序、字節(jié)對(duì)齊的理解.docx_第3頁(yè)
字節(jié)序、字節(jié)對(duì)齊的理解.docx_第4頁(yè)
字節(jié)序、字節(jié)對(duì)齊的理解.docx_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

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ì)立的含義,但這并不是必然的,例如你可以認(rèn)為 1 代表 5 個(gè)人, 0 代表 8 個(gè)人),對(duì)于絕大多數(shù)的計(jì)算要求,單個(gè)位顯然不能滿足。因此,我們通常都會(huì)使用一連串的位,我們可以稱之為位串( bit string ,請(qǐng)愛(ài)好質(zhì)疑的的朋友注意,此術(shù)語(yǔ)非我杜撰)。由于種種原因,計(jì)算機(jī)系統(tǒng)都不會(huì)讓你使用任意長(zhǎng)度的位串,而是使用某個(gè)特定長(zhǎng)度的位串。一些常見(jiàn)的位串長(zhǎng)度 形式具有約定好的名稱,如,半字節(jié)( nibble ,貌似用的不多)代表四個(gè)位的組合,字節(jié)( byte ,主角出場(chǎng)?。┐?8 個(gè)位的組合。再多的還有,字( word )、雙字( Double word ,通常簡(jiǎn)寫為 Dword )、四字( Quad word ,經(jīng)常簡(jiǎn)寫為 Qword )、十字節(jié)( Ten byte ,也簡(jiǎn)寫為 Tbyte )。在這些里面,字( 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 體系中的術(shù)語(yǔ),其他的體系中可能并不使用。在本文中,我們按照 Intel 的慣例來(lái)使用字或者 word 這一術(shù)語(yǔ)。一個(gè)字節(jié)中共有 8 個(gè)數(shù)據(jù)位,有時(shí)需要用圖表逐位表述各個(gè)位。習(xí)慣上,我們按照下面的圖來(lái)排列各個(gè)位的順序,即,按照從右到左的順序,依次為最低位(從第 0 位開始)到最高位(對(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 位,而在某些專業(yè)領(lǐng)域(如高端顯卡),處理器字長(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 ?,F(xiàn)在,問(wèn)題來(lái)了,如果有一個(gè)內(nèi)存操作,要從地址 0x06 處讀取一個(gè)字,得到的結(jié)果是多少呢?答案是:不一定。這里的本質(zhì)問(wèn)題在于,如何把多字節(jié)的對(duì)象存儲(chǔ)到內(nèi)存中去呢?即使使用最正常的思維去考慮這個(gè)問(wèn)題,你也會(huì)發(fā)現(xiàn)有兩種方法。第一種方法是,把最低端的 字節(jié)放到指定的起始位置(即基地址處),然后按照從低到高的字節(jié)順序把其余字節(jié)依次放入,如下圖 a ;另一種方法非常類似,但是對(duì)高端字節(jié)和低端字節(jié)的處理順序正好相反,如下圖 b (我確信你還可以想出其他的方法,但是除二字節(jié)的情況外,必然會(huì)打破字節(jié)排列順序的一致性,我視之為反常規(guī)思維的產(chǎn)物,此處暫不考慮)。圖 a圖 b在很久之前,哪一種存儲(chǔ)方式更為合理曾經(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)采用(如最近被蘋果公司徹底拋棄的 PowerPC ),因此上,我們不能稱之為罕見(jiàn)的用法。之所以造成事實(shí)上的不經(jīng)常見(jiàn)到,其原因正如我今天中午所得到的消息: Intel 的 CPU 占整個(gè)市場(chǎng)份額的 80% 以上。這兩種排列方式通常用小端( little endian )和大端( big endian )來(lái)稱謂。這兩個(gè)奇怪的名字據(jù)說(shuō)來(lái)源于童話格列佛游記,其中小人國(guó)里的公民為了雞蛋到底是應(yīng)該從小的一頭打開還是大的一頭打開而大起爭(zhēng)執(zhí)。 Intel 的方式對(duì)應(yīng)于“小端”,順便說(shuō)一句,大端的方式也有一個(gè)大公司的名字作為其代表,即最近開始沒(méi)落的 Motorola 。如果有誰(shuí)了解過(guò) TIFF 圖像文件格式,就會(huì)發(fā)現(xiàn)其文件頭中用以標(biāo)識(shí)文件數(shù)據(jù)字節(jié)序的標(biāo)志就是“ II ”和“ MM ”,分別對(duì)應(yīng)于 Intel 和 Motorola 的首字母。值得提醒一下,小端方式的排列與位的排列順序相一致,看上去似乎更協(xié)調(diào)一些?,F(xiàn)在我們可以回答上面的問(wèn)題了。對(duì)于小端字節(jié)序,我們?nèi)〉降淖郑渲禐?0x9abc ,而如果是大端字節(jié)序的話,就會(huì)取到 0xdef0 。4、 何時(shí)會(huì)出現(xiàn)字節(jié)序問(wèn)題字節(jié)序問(wèn)題主要出現(xiàn)在數(shù)據(jù)在不同平臺(tái)之間進(jìn)行交換時(shí),交換的途徑可能是網(wǎng)絡(luò)傳輸,也可能是文件復(fù)制。例如,如果你設(shè)計(jì)了一種可能會(huì)應(yīng)用于不同平臺(tái)的 文件格式,其中存儲(chǔ)了某些數(shù)據(jù)結(jié)構(gòu),則對(duì)于大小大于一個(gè)字節(jié)的數(shù)據(jù)就要明確地規(guī)定其遵循的字節(jié)序,以便各平臺(tái)上的處理程序可以在使用數(shù)據(jù)時(shí)實(shí)現(xiàn)做必要的轉(zhuǎn) 換。舉一個(gè)實(shí)際的例子。 Java 是一個(gè)跨平臺(tái)的編程語(yǔ)言,其可執(zhí)行文件(擴(kuò)展名為 .class ,使用的是一種機(jī)器無(wú)關(guān)的字節(jié)碼指令集)在理論上可以運(yùn)行于所有的實(shí)現(xiàn)了 Java 運(yùn)行時(shí)的平臺(tái)(包含有與特定平臺(tái)相關(guān)特性的除外)。編譯后的 .class 中一定保存有諸如 Integer 這樣類型的數(shù)據(jù),這就涉及到了字節(jié)序的確定,否則 .class 必然不能被采用了不同字節(jié)序的平臺(tái)同時(shí)正確加載并運(yùn)行。事實(shí)上, Java 語(yǔ)言采用的為大端字節(jié)序,這個(gè)一點(diǎn)都不奇怪,因?yàn)楫?dāng)初 SUN 公司自己的 SPARC 架構(gòu)就是采用的大端字節(jié)序。同樣的問(wèn)題和解決問(wèn)題的方式,也存在于操作系統(tǒng)新貴 android 系統(tǒng)上。網(wǎng)絡(luò)傳輸則是另一個(gè)典型場(chǎng)景。 TCP/IP 所采用的網(wǎng)絡(luò)傳輸字節(jié)序標(biāo)準(zhǔn)也是大端字節(jié)序,這個(gè)也不必奇怪,因?yàn)?TCP/IP 是從 UNIX 系統(tǒng)發(fā)展起來(lái)的,而絕大部分的 UNIX 系統(tǒng)在很長(zhǎng)的一段時(shí)間內(nèi)都沒(méi)有運(yùn)行于 Intel 體系架構(gòu)上的版本。處理字節(jié)序問(wèn)題的手段非常簡(jiǎn)單,也就是對(duì)數(shù)據(jù)進(jìn)行必要的轉(zhuǎn)換:將十六進(jìn)制的數(shù)字從兩端開始交換,直至移動(dòng)到數(shù)據(jù)的中心,交換完成為止。交換的結(jié)果就好像物體與鏡面之內(nèi)的成像互換了位置,因此也被稱為鏡像交換( mirror-image swap )。請(qǐng)參看下圖:5、 如何在程序中判斷字節(jié)序在實(shí)際的工作中,有時(shí)需要對(duì)字節(jié)序進(jìn)行判斷,然后予以不同的處理。一般的來(lái)說(shuō),編譯后的程序通常只能運(yùn)行在特定的平臺(tái)之上,其所采用的字節(jié)序方式在 編譯時(shí)即可確定,在這種情況下,程序源代碼中通常是把字節(jié)序的判別作為條件編譯的判斷語(yǔ)句,而不會(huì)判斷代碼放在真正的可執(zhí)行代碼中。在這里,需要使用我們的老朋友 宏。以下是一個(gè)真實(shí)的跨平臺(tái)工程中代碼,清晰起見(jiàn),我稍做了修改:#define SGE_LITTLE_ENDIAN 1234#define SGE_BIG_ENDIAN 4321#ifndef SGE_BYTEORDER#if defined(_hppa_) | defined(_m68k_) | defined(mc68000) | defined(_M_M68K) | (defined(_MIPS_) & defined(_MISPEB_) | defined(_ppc_) | defined(_POWERPC_) | defined(_M_PPC) | defined(_sparc_)#define SGE_BYTEORDER SGE_BIG_ENDIAN#else#define SGE_BYTEORDER SGE_LITTLE_ENDIAN#endif#endif以上為根據(jù)平臺(tái)的預(yù)定義宏所作的前期工作,將之存入一個(gè)頭文件中,然后包含到源代碼文件中使用。在需要進(jìn)行判斷的時(shí)候,則像以下代碼這樣使用:#if SGE_BYTEORDER = SGE_BIG_ENDIAN #define SwapWordLe(w) SwapWord(w) #else #define SwapWordLe(w) (w) #endif由于這兩個(gè)宏實(shí)際上被定義成了常量數(shù)值,因此也可以被用到可執(zhí)行代碼中,進(jìn)行執(zhí)行期的動(dòng)態(tài)判斷:if(SGE_BYTEORDER = SGE_BIG_ENDIAN) return r 16 | g 8 | b; else return r | g 8 | b y; / 執(zhí)行一個(gè)非對(duì)齊的讀取操作typedef struct short x; char y; _pac

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論