




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【大端(BigEndian)與小端(LittleEndian簡介】ByteEndian是指字節(jié)在內(nèi)存中的組織,所以也稱它為ByteOrdering,或ByteOrder。對于數(shù)據(jù)中跨越多個(gè)字節(jié)的對象,我們必須為它建立這樣的約定:(1) 它的地址是多少?(2) 它的字節(jié)在內(nèi)存中是如何組織的?針對第一個(gè)問題,有這樣的解釋:對于跨越多個(gè)字節(jié)的對象,一般它所占的字節(jié)都是連續(xù)的,它的地址等于它所占字節(jié)最低地址。(鏈表可能是個(gè)例外,但鏈表的地址可看作鏈表頭的地址)。比如:int,它的地址為0x100。那么它占據(jù)了內(nèi)存中的0x100,0x101,0x102, 0x103這四個(gè)字節(jié)(32位系統(tǒng),所以int占用4個(gè)字節(jié))。上面只是內(nèi)存字節(jié)組織的一種情況:多字節(jié)對象在內(nèi)存中的組織有一般有兩種約定??紤]一個(gè)W位的整數(shù)。它的各位表達(dá)如下:[Xw-1,Xw-2, ...,X1, X0],它的MSB(MostSignificantByte,最高有效字節(jié))為[Xw-1,Xw-2, ...Xw-8];LSB(LeastSignificantByte最低有效字節(jié))為[X7,X6,....X0]。其余的字節(jié)位于MSB,LSB之間。LSB和MSB誰位于內(nèi)存的最低地址,即誰代表該對象的地址?這就引出了大端(BigEndian)與小端(LittleEndian的問題。如果LSB在MSB前面,既LSB是低地址,則該機(jī)器是小端;反之則是大端。大端和小端是針對字節(jié)為單位定義的。DEC(DigitalEquipmentCorporation ,現(xiàn)在是Compaq 公司的一部分)和Intel的機(jī)器(X86平臺(tái))一般采用小端。IBM,Motorola(PowerPC),Sun的機(jī)器一般采用大端。當(dāng)然,這不代表所有情況。有的CPU即能工作于小端,又能工作于大端,比如ARM,Alpha,摩托羅拉的PowerPC。具體情形參考處理器手冊。具體這類CPU是大端還是小端,應(yīng)該和具體設(shè)置有關(guān)。(如,PowerPC支持little-endiar字節(jié)序,但在默認(rèn)配置時(shí)是big-endian字節(jié)序)一般來說,大部分用戶的操作系統(tǒng)(如windows,FreeBsd,Linux)是LittleEndian的。少部分,如MACOS,是BigEndian的。所以說,LittleEndian還是BigEndian與操作系統(tǒng)和芯片類型都有關(guān)系。Linux系統(tǒng)中,你可以在/usr/include/中(包括子目錄)查找字符串BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER),確定其值。BYTE_ORDER中文稱為字節(jié)序。這個(gè)值一般在endian.h或machine/endian.h文件中可以找到,有時(shí)在feature.h中,不同的操作系統(tǒng)可能有所不同。對于一個(gè)數(shù)0x1122使用LittleEndian方式時(shí),低字節(jié)存儲(chǔ)0x22,高字節(jié)存儲(chǔ)0x11而使用BigEndian方式時(shí),低字節(jié)存儲(chǔ)0x11,高字節(jié)存儲(chǔ)0x22【用函數(shù)判斷系統(tǒng)是BigEndian還是LittleEndian]boolIsBig_Endian()//如果字節(jié)序?yàn)閎ig-endian,返回true;〃反之為 little-endian,返回false{unsignedshorttest=x1122;if(*((unsignedchar*)&test)==0x11)returnTRUE;elsereturnFALSE;深入淺出大端和小端文章一:端模式(Endian)的這個(gè)詞出自JonathanSwift書寫的《格列佛游記》。這本書根據(jù)將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為BigEndian,從尖頭開始將雞蛋敲開的人被歸為LittileEndian。小人國的內(nèi)戰(zhàn)就源于吃雞蛋時(shí)是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開。在計(jì)算機(jī)業(yè)BigEndian和LittleEndian也幾乎引起一場戰(zhàn)爭。在計(jì)算機(jī)業(yè)界,Endian表示數(shù)據(jù)在存儲(chǔ)器中的存放順序。下文舉例說明在計(jì)算機(jī)中大小端模式的區(qū)別。如果將一個(gè)32位的整數(shù)0x12345678存放到一個(gè)整型變量(int)中,這個(gè)整型變量采用大端或者小端模式在內(nèi)存中的存儲(chǔ)由下表所示。為簡單起見,本書使用OP0表示一個(gè)32位數(shù)據(jù)的最高字節(jié)MSB(MostSignificantByte),使用OP3表示一個(gè)32位數(shù)據(jù)最低字節(jié)LSB(LeastSignificantByte)。地址偏移大端模式小端模式0x0012(OP0)78(OP3)0x0134(OP1)56(OP2)0x0256(OP2)34(OP1)0x0378(OP3)12(OP0)如果將一個(gè)16位的整數(shù)0x1234存放到一個(gè)短整型變量(short)中。這個(gè)短整型變量在內(nèi)存中的存儲(chǔ)在大小端模式由下表所示。地址偏移大端模式小端模式0x0012(OP0)34(OP1)0x0134(OP1)12(OP0)由上表所知,采用大小模式對數(shù)據(jù)進(jìn)行存放的主要區(qū)別在于在存放的字節(jié)順序,大端方式將高位存放在低地址,小端方式將高位存放在高地址。采用大端方式進(jìn)行數(shù)據(jù)存放符合人類的正常思維,而采用小端方式進(jìn)行數(shù)據(jù)存放利于計(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ì)中也存在著使用大端或者小端進(jìn)行數(shù)據(jù)存放的選擇。因此在一個(gè)處理器系統(tǒng)中,有可能存在大端和小端模式同時(shí)存在的現(xiàn)象。這一現(xiàn)象為系統(tǒng)的軟硬件設(shè)計(jì)帶來了不小的麻煩,這要求系統(tǒng)設(shè)計(jì)工程師,必須深入理解大端和小端模式的差別。大端與小端模式的差別體現(xiàn)在一個(gè)處理器的寄存器,指令集,系統(tǒng)總線等各個(gè)層次中。1.1.1從軟件的角度理解端模式從軟件的角度上,不同端模式的處理器進(jìn)行數(shù)據(jù)傳遞時(shí)必須要考慮端模式的不同。如進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳遞時(shí),必須要考慮端模式的轉(zhuǎn)換。有過Socket接口編程經(jīng)驗(yàn)的程序員一定使用過以下幾個(gè)函數(shù)用于大小端字節(jié)序的轉(zhuǎn)換。#definentohs(n)//16位數(shù)據(jù)類型網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序的轉(zhuǎn)換#definehtons(n)//16位數(shù)據(jù)類型主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序的轉(zhuǎn)換#definentohl(n)//32位數(shù)據(jù)類型網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序的轉(zhuǎn)換#definehtonl(n)//32位數(shù)據(jù)類型主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序的轉(zhuǎn)換其中互聯(lián)網(wǎng)使用的網(wǎng)絡(luò)字節(jié)順序采用大端模式進(jìn)行編址,而主機(jī)字節(jié)順序根據(jù)處理器的不同而不同,如PowerPC處理器使用大端模式,而Pentuim處理器使用小端模式。大端模式處理器的字節(jié)序到網(wǎng)絡(luò)字節(jié)序不需要轉(zhuǎn)換,此時(shí)ntohs(n)=n,ntohl=n;而小端模式處理器的字節(jié)序到網(wǎng)絡(luò)字節(jié)必須要進(jìn)行轉(zhuǎn)換,此時(shí)ntohs(n)=__swab16(n),ntohl=__swab32(n)。__swab16與__swab32函數(shù)定義如下所示。#define___swab16(x)__u16__x=(x);((__u16)((((__u16)(__x)&(__u16)0x00ffU)<<8)|(((__u16)(__x)&(__u16)0xff00U)>>8)));}#define___swab32(x){__u32__x=(x);((__u32)((((__u32)(__x)&(__u32)0x000000ffUL)<<24)|(((__u32)(__x)&(__u32)0x0000ff00UL)<<8)|(((__u32)(__x)&(__u32)0x00ff0000UL)>>8)|(((__u32)(__x)&(__u32)0xff000000UL)>>24)));}PowerPC處理器提供了lwbrx,lhbrx,stwbrx,sthbrx四條指令用于處理字節(jié)序的轉(zhuǎn)換以優(yōu)化__swab16和__swap32這類函數(shù)。此外PowerPC處理器中的rlwimi指令也可以用來實(shí)現(xiàn)__swab16和__swap32這類函數(shù)。在LinuxPowerPC中,定義了一系列有關(guān)字節(jié)序轉(zhuǎn)換的函數(shù),其詳細(xì)定義在?/include/asm-powerpc/byteorder.h文件中。程序員在對普通文件進(jìn)行處理也需要考慮端模式問題。在大端模式的處理器下對文件的32,16位讀寫操作所得到的結(jié)果與小端模式的處理器不同。讀者單純從軟件的角度理解上遠(yuǎn)遠(yuǎn)不能真正理解大小端模式的區(qū)別。事實(shí)上,真正的理解大小端模式的區(qū)別,必須要從系統(tǒng)的角度,從指令集,寄存器和數(shù)據(jù)總線上深入理解,大小端模式的區(qū)別。1.1.2從系統(tǒng)的角度理解端模式除了4.2.1節(jié)中,軟件上對不同端模式編程上的差異,處理器在硬件上也由于端模式問題在設(shè)計(jì)中有所不同。從系統(tǒng)的角度上看,端模式問題對軟件和硬件的設(shè)計(jì)帶來了不同的影響,當(dāng)一個(gè)處理器系統(tǒng)中大小端模式同時(shí)存在時(shí),必須要對這些不同端模式的訪問進(jìn)行特殊的處理。PowerPC處理器主導(dǎo)網(wǎng)絡(luò)市場,可以說絕大多數(shù)的通信設(shè)備都使用PowerPC處理器進(jìn)行協(xié)議處理和其他控制信息的處理,這也可能也是在網(wǎng)絡(luò)上的絕大多數(shù)協(xié)議都采用大端編址方式的原因。因此在有關(guān)網(wǎng)絡(luò)協(xié)議的軟件設(shè)計(jì)中,使用小端方式的處理器需要在軟件中處理端模式的轉(zhuǎn)變。而Pentium主導(dǎo)個(gè)人機(jī)市場,因此多數(shù)用于個(gè)人機(jī)的外設(shè)都采用小端模式,包括一些在網(wǎng)絡(luò)設(shè)備中使用的PCI總線,F(xiàn)lash等設(shè)備,這也要求硬件工程師在硬件設(shè)計(jì)中注意端模式的轉(zhuǎn)換。本書中的小端外設(shè)是指這種外設(shè)中的寄存器以小端方式進(jìn)行存儲(chǔ),如PCI設(shè)備的配置空間,NORFLASH中的寄存器等等。對于有些設(shè)備,如DDR顆粒,沒有以小端方式存儲(chǔ)的寄存器,因此從邏輯上講并不需要對端模式進(jìn)行轉(zhuǎn)換。在設(shè)計(jì)中,只需要將雙方數(shù)據(jù)總線進(jìn)行一一對應(yīng)的互連,而不需要進(jìn)行數(shù)據(jù)總線的轉(zhuǎn)換。如果從實(shí)際應(yīng)用的角度說,采用小端模式的處理器需要在軟件中處理端模式的轉(zhuǎn)換,因?yàn)椴捎眯《四J降奶幚砥髟谂c小端外設(shè)互連時(shí),不需要任何轉(zhuǎn)換。而采用大端模式的處理器需要在硬件設(shè)計(jì)時(shí)處理端模式的轉(zhuǎn)換。大端模式處理器需要在寄存器,指令集,數(shù)據(jù)總線及數(shù)據(jù)總線與小端外設(shè)的連接等等多個(gè)方面進(jìn)行處理,以解決與小端外設(shè)連接時(shí)的端模式轉(zhuǎn)換問題。在寄存器和數(shù)據(jù)總線的位序定義上,基于大小端模式的處理器有所不同。一個(gè)采用大端模式的32位處理器,如基于E500內(nèi)核的MPC8541,將其寄存器的最高位msb(mostsignificantbit)定義為0,最低位Isb(leasesignificantbit)定義為31;而小端模式的32位處理器,將其寄存器的最高位定義為31,低位地址定義為0。與此向?qū)?yīng),采用大端模式的32位處理器數(shù)據(jù)總線的最高位為0,最高位為31;采用小端模式的32位處理器的數(shù)據(jù)總線的最高位為31,最低位為0。如圖4.5所示。OP0OP1OP2OP3OP0OP1OP2OP3310310圖4.5大小端模式處理器的寄存器的定義大端模式處理器寄存器位序定義小端模式處理器寄存器位序定義大小端模式處理器外部總線的位序也遵循著同樣的規(guī)律,根據(jù)所采用的數(shù)據(jù)總線是32位,16位和8位,大小端處理器外部總線的位序有所不同。“ 大端模式下32位數(shù)據(jù)總線的msb是第0位,MSB是數(shù)據(jù)總線的第0~7的字段;而Isb是第31位,LSB是第24~31字段。小端模式下32位總線的msb是第31位,MSB是數(shù)據(jù)總線的第31~24位,Isb是第0位,LSB是7~0字段?!?大端模式下16位數(shù)據(jù)總線的msb是第0位,MSB是數(shù)據(jù)總線的第0~7的字段;而Isb是第15位,LSB是第8~15字段。小端模式下16位總線的msb是第15位,MSB是數(shù)據(jù)總線的第15~7位,Isb是第0位,LSB是7~0字段?!?大端模式下8位數(shù)據(jù)總線的msb是第0位,MSB是數(shù)據(jù)總線的第0~7的字段;而Isb是第7位,LSB是第0~7字段。小端模式下8位總線的msb是第7位,MSB是數(shù)據(jù)總線的第7~0位,Isb是第0位,LSB是7~0字段。由上分析,我們可以得知對于8位,16位和32位寬度的數(shù)據(jù)總線,采用大端模式時(shí)數(shù)據(jù)總線的msb和MSB的位置都不會(huì)發(fā)生變化,而采用小端模式時(shí)數(shù)據(jù)總線的Isb和LSB位置也不會(huì)發(fā)生變化。為此,大端模式的處理器對8位,16位和32位的內(nèi)存訪問(包括外設(shè)的訪問)一般都包含第0~7字段,即MSB。小端模式的處理器對8位,16位和32位的內(nèi)存訪問都包含第7~0位,小端方式的第7~0字段,即LSB。由于大小端處理器的數(shù)據(jù)總線其8位,16位和32位寬度的數(shù)據(jù)總線的定義不同,因此需要分別進(jìn)行討論在系統(tǒng)級別上如何處理端模式轉(zhuǎn)換。在一個(gè)大端處理器系統(tǒng)中,需要處理大端處理器對小端外設(shè)的訪問。大端處理器對32位小端外設(shè)進(jìn)行訪問大端處理器采用32位總線與小端外設(shè)進(jìn)行訪問時(shí),大端處理器的32位數(shù)據(jù)總線的第0~7位用來處理OPO,第8~15位用來處理OP1,第16~23位用來處理OP2,第24~31位用來處理OP3。而32位的小端設(shè)備使用數(shù)據(jù)總線的第31~24位用來處理OP0,第23~16位用來處理OP1,第15~8位用來處理OP2,第7~0位用來處理OP3。大端處理器,如MPC8541,使用stw,sth,stb和Iwz,lhz,Ibz指令對32位的外部設(shè)備進(jìn)行訪問。在這些指令結(jié)束后,存放在外部設(shè)備的數(shù)據(jù)將被讀入MPC8541的通用寄存器中。為保證軟件的一致性,當(dāng)訪問結(jié)束后,存放在通用寄存器的字節(jié)序,即OPO,OP1,OP2和0P3必須要和存放在小端外設(shè)的字節(jié)序一致。此時(shí)在使用大端處理器的數(shù)據(jù)總線連接小端外設(shè)時(shí)必須要進(jìn)行一定的處理,按照某種拓?fù)浣Y(jié)構(gòu)連接以保證軟件的一致性。大端處理器數(shù)據(jù)總線與小端外設(shè)進(jìn)行連接的拓?fù)浣Y(jié)構(gòu)如圖4.6所示。OP0OP1OP2OP331310781516232424231615870大端處理器的32位數(shù)據(jù)總線小端設(shè)備的32位總線接口圖4.6大端處理器與小端外設(shè)的32位連接OP0OP1OP2OP3如圖4.6所示,采用大端處理器訪問小端設(shè)備時(shí),將各自的OP0~OP3字段直接相連。在大端處理器的32位數(shù)據(jù)總線的最高位為0,最低位為31;而小端設(shè)備的最高位為31,最低位為0。因此硬件工程師在進(jìn)行信號連接時(shí)需要將采用大端處理器的0~31位分別與小端設(shè)備的31~0位一一對應(yīng),進(jìn)行互連。大端處理器對8,16位小端外設(shè)進(jìn)行訪問大端處理器使用8位,16位數(shù)據(jù)總線對8位,16位的小端外設(shè)進(jìn)行連接。對于32位處理器,用來連接外設(shè)的總線一般是32位。因此體系結(jié)構(gòu)工程師在進(jìn)行大端處理器總線設(shè)計(jì)時(shí)有兩種選擇,是采用32位總線的高端部分(第0~15字段)還是低端部分(第16~31字段)連接小端設(shè)備。PowerPC處理器使用32位總線的高端部分,即數(shù)據(jù)總線的第0~15位連接16位的小端設(shè)備,使用0~7位連接8位的小端設(shè)備。PowerPC處理器采用16位總線與16位的小端外設(shè)進(jìn)行訪問時(shí),PowerPC處理器的16位數(shù)據(jù)總線的第0~7位用來處理OP0,第8~15位用來處理OP1。而16位的小端設(shè)備使用數(shù)據(jù)總線的第15~8位用來處理OP0,第7~0位用來處理OP1。PowerPC處理器采用8位總線與8位的小端外設(shè)進(jìn)行訪問時(shí),PowerPC處理器的8位數(shù)據(jù)總線的第0~7字段用來處理OP0。而8位的小端設(shè)備使用數(shù)據(jù)總線的第7~0位用來處理OP1。大端處理器與小端外設(shè)的連接關(guān)系如圖4.7所示。OP0OP1OP0OP11507815870大端處理器的8/16位數(shù)據(jù)總線小端設(shè)備的8/16位總線接口圖4.7大端處理器與小端外設(shè)的8/16位連接OP0OP07070與32位總線接口類似,PowerPC處理器可以使用stw,sth,stb和lwz,Ihz,Ibz指令對32位的外部設(shè)備進(jìn)行訪問,并將數(shù)據(jù)存放在相應(yīng)的通用寄存器中。當(dāng)訪問結(jié)束后,存放在通用寄存器的字節(jié)序,即OP0,OP1必須要和存放在小端外設(shè)的字節(jié)序一致。PowerPC處理器對8位的小端外設(shè)進(jìn)行訪問時(shí),一個(gè)總線周期只能訪問8位數(shù)據(jù),如果處理器使用stw或者Iwz指令訪問8位的小端設(shè)備內(nèi)的32位數(shù)據(jù)時(shí),在數(shù)據(jù)總線上將OPO,OP1,OP2和OP3依次傳遞到PowerPC的通用寄存器中。PowerPC處理器對16位的小端外設(shè)進(jìn)行訪問時(shí),一個(gè)總線周期只能訪問16位數(shù)據(jù),如果處理器使用stw或者Iwz指令訪問16位的小端設(shè)備內(nèi)的32位數(shù)據(jù)時(shí),在數(shù)據(jù)總線上將OP0~1和OP2~3依次傳遞到PowerPC的通用寄存器中。PowerPC處理器使用sth或者Ihz指令訪問16位的小端設(shè)備時(shí),16位的小端設(shè)備將數(shù)據(jù)的第15~0位,傳遞到PowerPC處理器的總線的第0~15位,然后再將數(shù)據(jù)最終傳遞給相應(yīng)的通用寄存器。這里有許多讀者會(huì)感到困惑,因?yàn)闉榱吮WC軟件的一致性,PowerPC處理器使用Ihz指令訪問16位的小端設(shè)備的16位寄存器時(shí),需要將結(jié)果保存在通用寄存器的第16~31位,而不是0~15位。究竟PowerPC處理器是如何將系統(tǒng)總線中0~15位的數(shù)據(jù)搬移到寄存器的第16~31位中的呢?為此我們需要對Ihz指令進(jìn)行分析。IhzrD,d(rA)ifrA=0thenb—0elseb—(rA)EA<—b+EXTS(d)rD—(24)0||MEM(EA,1)由Ihz指令的以上描述得知Ihz指令將來自數(shù)據(jù)總線上的OP0與OP1直接存入寄存器的第16~31位,而將第0~15位直接清零。PowerPC處理器使用stb或者lbz指令訪問8位的小端設(shè)備時(shí),8位的小端設(shè)備將數(shù)據(jù)的第7~0位,傳遞到PowerPC處理器的總線的第0~7位,然后再將數(shù)據(jù)最終傳遞給相應(yīng)的通用寄存器,lbz指令的描述如下所示。lbzrD,d(rA)ifrA=0thenb—0elseb—(rA)EA<—b+EXTS(d)rD—(24)0||MEM(EA,1)由Ihz指令的以上描述得知Ihz指令將來自數(shù)據(jù)總線上的OP0直接存入寄存器的第24~31位,而將第0~23位清零。本節(jié)分別描述了大端處理器的32位,16位及8位數(shù)據(jù)總線與32位,16位和8位的小端設(shè)備進(jìn)行連接。如果大端處理器的數(shù)據(jù)總線需要同時(shí)支持小端設(shè)備的32位,16位及8位的數(shù)據(jù)傳送方式,端模式的處理將會(huì)更加復(fù)雜。IC的設(shè)計(jì)人員在設(shè)計(jì)PCI總線橋片的時(shí)候?qū)?huì)遇到這一類問題,此時(shí)設(shè)計(jì)人員將使用多路總線開關(guān)來解決這一問題。端模式問題的解決需要軟硬件協(xié)調(diào)處理,并在指令集上加以支持。對于小端處理器而言,需要使用軟件轉(zhuǎn)換的方法實(shí)現(xiàn)大小端模式的匹配;對于大端處理器而言,在外部數(shù)據(jù)總線與小端外設(shè)的連接時(shí)必須要考慮數(shù)據(jù)總線連接的拓?fù)浣Y(jié)構(gòu)。轉(zhuǎn)載:/boshenshen/blog/item/8c9d1e647e8e2ef4f6365452.html文章二:大端(big-endian)和小端(little-endia門)<轉(zhuǎn)>2007-12-0720:36補(bǔ):x86機(jī)是小端(修改分區(qū)表時(shí)要注意),單片機(jī)一般為大端今天碰一個(gè)關(guān)于字節(jié)順序的問題,雖然看起來很簡單,但一直都沒怎么完全明白這個(gè)東西,索性就找了下資料,把它弄清楚.因?yàn)楝F(xiàn)行的計(jì)算機(jī)都是以八位一個(gè)字節(jié)為存儲(chǔ)單位,那么一個(gè)16位的整數(shù),也就是C語言中的short,在內(nèi)存中可能有兩種存儲(chǔ)順序big-endian和litte-endian.考慮一個(gè)short整數(shù)0x3132(0x32是低位,0x31是高位),把它賦值給一個(gè)short變量,那么它在內(nèi)存中的存儲(chǔ)可能有如下兩種情況:大端字節(jié)(Big-endian): >>>>>>>>內(nèi)存地址增大方向short變量地址0x1000 0x1001I I| 0x31 | 0x32I I 高位字節(jié)在低位字節(jié)的前面,也就是高位在內(nèi)存地址低的一端?可以這樣記住(大端->高位->在前->正常的邏輯順序)小端字節(jié)(little-endian): >>>>>>>>內(nèi)存地址增大方向short變量地址0x1000 0x1001||| 0x32 | 0x31| | 低位字節(jié)在高位字節(jié)的前面,也就是低位在內(nèi)存地址低的一端?可以這樣記住(小端->低位->在前->與正常邏輯順序相反)可以做個(gè)實(shí)驗(yàn)在windows上下如下程序#inelude<stdio.h>#inelude<assert.h>voidmain(void){shorttest;FILE*fp;test=0x3132;//(31ASIIC碼的T,32ASIIC碼的2)if((fp=fopen("c:\\test.txt","wb"))==NULL)assert(0);fwrite(&test,sizeof(short),1,fp);fclose(fp);}然后在C盤下打開test.txt文件,可以看見內(nèi)容是21,而test等于0x3132,可以明顯的看出來x86的字節(jié)順序是低位在前?如果我們把這段同樣的代碼放到(big-endian)的機(jī)器上執(zhí)行,那么打出來的文件就是12?這在本機(jī)中使用是沒有問題的.但當(dāng)你把這個(gè)文件從一個(gè)big-endian機(jī)器復(fù)制到一個(gè)little-endian機(jī)器上時(shí)就出現(xiàn)問題了.如上述例子,我們在big-endian的機(jī)器上創(chuàng)建了這個(gè)test文件,把其復(fù)制到little-endian的機(jī)器上再用fread讀到一個(gè)short里面,我們得到的就不再是0x3132而是0x3231了,這樣讀到的數(shù)據(jù)就是錯(cuò)誤的,所以在兩個(gè)字節(jié)順序不一樣的機(jī)器上傳輸數(shù)據(jù)時(shí)需要特別小心字節(jié)順序,理解了字節(jié)順序在可以幫助我們寫出移植行更高的代碼?正因?yàn)橛凶止?jié)順序的差別,所以在網(wǎng)絡(luò)傳輸?shù)臅r(shí)候定義了所有字節(jié)順序相關(guān)的數(shù)據(jù)都使用big-endian,BSD的代碼中定義了四個(gè)宏來處理:#definentohs(n)#definehtons(n)#definentohl(n)#definehton1(n)〃網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序n代表net,h代表host,s代表short〃主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序n代表net,h代表host,s代表short〃網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序n代表net,h代表host,丨代表long〃主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序n代表net,h代表host,丨代表long舉例說明下這其中一個(gè)宏的實(shí)現(xiàn):#definesw16(x)\((short)(\(((short)(x)&(short)OxOOffU)<<8)|\(((short)(x)&(short)0xff00U)>>8)))這里實(shí)現(xiàn)的是一個(gè)交換兩個(gè)字節(jié)順序?其他幾個(gè)宏類似.我們改寫一下上面的程序#inelude<stdio.h>#inelude<assert.h>#definesw16(x)\((short)(\(((short)(x)&(short)OxOOffU)<<8)|\(((short)(x)&(short)OxffOOU)>>8)))//因?yàn)閤86下面是低位在前,需要交換一下變成網(wǎng)絡(luò)字節(jié)順序#definehtons(x)sw16(x)voidmain(void){shorttest;FILE*fp;test=htons(Ox3132);//(31ASIIC碼的T,32ASIIC碼的2)if((fp=fopen("c:\\test.txt","wb"))==NULL)assert(O);fwrite(&test,sizeof(short),1,fp);fclose(fp);}如果在高字節(jié)在前的機(jī)器上,由于與網(wǎng)絡(luò)字節(jié)順序一致,所以我們什么都不干就可以了,只需要把#definehtons(x)sw16(x)宏替換為#definehtons(x)(x).一開始我在理解這個(gè)問題時(shí),總在想為什么其他數(shù)據(jù)不用交換字節(jié)順序?比如說我們write一塊buffer到文件,最后終于想明白了,因?yàn)槎际莡nsignedchar類型一個(gè)字節(jié)一個(gè)字節(jié)的寫進(jìn)去,這個(gè)順序是固定的,不存在字節(jié)順序的問題,夠笨啊??/liyangzhao/blog/item/277e2ce7e1O5cf2db8382OOf.html文章big-endian和little-endian這兩個(gè)術(shù)語來自JonathanSwift在十八世紀(jì)的嘲諷作品Gulliver'sTravelsBlefuSCU帝國的國民被根據(jù)吃雞蛋的方式劃分為兩個(gè)部分:一部分在吃雞蛋的時(shí)候從雞蛋的大端(bigend)開始,而另一部分則從雞蛋的小端(littleend)開
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個(gè)人財(cái)產(chǎn)安全設(shè)備銷售與租賃合同
- 外墻保溫裝飾一體板施工合同
- 學(xué)校專家聘用合同
- 關(guān)于提高工作效率的溝通機(jī)制研究報(bào)告
- 鄉(xiāng)村發(fā)展行動(dòng)指導(dǎo)書
- 制造業(yè)企業(yè)數(shù)字化轉(zhuǎn)型實(shí)施方案
- 核電安全施工方案模板
- 籃球場工程施工方案
- 河南電力電纜線槽施工方案
- 建筑工程切險(xiǎn)保險(xiǎn)合同
- 2024年全國高考體育單招考試語文試卷試題(含答案詳解)
- 藥品養(yǎng)護(hù)記錄表
- 校級課題立項(xiàng)評審工作方案
- 現(xiàn)代密碼學(xué)第二講古典密碼學(xué)
- 醫(yī)院后勤保障部門考核標(biāo)準(zhǔn)
- 大學(xué)語文優(yōu)質(zhì)課件《盛唐-李白》
- 《做自己情緒的主人》課件
- 產(chǎn)品、過程質(zhì)量檢查清單
- 設(shè)備外協(xié)加工維修單
- 【基于GONE理論的宜華生活公司財(cái)務(wù)舞弊的案例分析18000字(論文)】
評論
0/150
提交評論