MSB與LSB
Most Significant Bit, Last(Least) Significant Bit
最高有效位(MSB)
指二進(jìn)制中最高值的比特。在16比特的數(shù)字音頻中,其第1個(gè)比特便對(duì)16bit的字的數(shù)值有最大的影響。例如,在十進(jìn)制的15,389這一數(shù)字中,相當(dāng)于萬數(shù)那1行(1)的數(shù)字便對(duì)數(shù)值的影響最大。比較與之相反的“最低有效位”(LSB)。
MSB高位前導(dǎo),LSB低位前導(dǎo)。
談到字節(jié)序的問題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存儲(chǔ)數(shù)據(jù),而x86系列則采用little endian方式存儲(chǔ)數(shù)據(jù)。那么究竟什么是big endian,什么又是little endian呢?
其實(shí)big endian是指低地址存放最高有效字節(jié)(MSB),而little endian則是低地址存放最低有效字節(jié)(LSB)。
用文字說明可能比較抽象,下面用圖像加以說明。比如數(shù)字0x12345678在兩種不同字節(jié)序CPU中的存儲(chǔ)順序如下所示:
Big Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 12 | 34 | 56 | 78 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Little Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 78 | 56 | 34 | 12 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
從上面兩圖可以看出,采用big endian方式存儲(chǔ)數(shù)據(jù)是符合我們?nèi)祟惖乃季S習(xí)慣的。而
little endian,!@#$%^&*,見鬼去吧 -_-|||
為什么要注意字節(jié)序的問題呢?你可能這么問。當(dāng)然,如果你寫的程序只在單機(jī)環(huán)境下面運(yùn)行,并且不和別人的程序打交道,那么你完全可以忽略字節(jié)序的存在。但是,如果你的程序要跟別人的程序產(chǎn)生交互呢?在這里我想說說兩種語言。C/C++語言編寫的程序里數(shù)據(jù)存儲(chǔ)順序是跟編譯平臺(tái)所在的CPU相關(guān)的,而J***A編寫的程序則唯一采用big endian方式來存儲(chǔ)數(shù)據(jù)。試想,如果你用C/C++語言在x86平臺(tái)下編寫的程序跟別人的J***A程序互通時(shí)會(huì)產(chǎn)生什么結(jié)果?就拿上面的0x12345678來說,你的程序傳遞給別人的一個(gè)數(shù)據(jù),將指向0x12345678的指針傳給了J***A程序,由于J***A采取big endian方式存儲(chǔ)數(shù)據(jù),很自然的它會(huì)將你的數(shù)據(jù)翻譯為0x78563412。什么?竟然變成另外一個(gè)數(shù)字了?是的,就是這種后果。因此,在你的C程序傳給J***A程序之前有必要進(jìn)行字節(jié)序的轉(zhuǎn)換工作。
無獨(dú)有偶,所有網(wǎng)絡(luò)協(xié)議也都是采用big endian的方式來傳輸數(shù)據(jù)的。所以有時(shí)我們也會(huì)把
big endian方式稱之為網(wǎng)絡(luò)字節(jié)序。當(dāng)兩臺(tái)采用不同字節(jié)序的主機(jī)通信時(shí),在發(fā)送數(shù)據(jù)之前都必須經(jīng)過字節(jié)序的轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)序后再進(jìn)行傳輸。ANSI C中提供了下面四個(gè)轉(zhuǎn)換字節(jié)序的宏。
·BE和LE一文的補(bǔ)完
我在8月9號(hào)的《Big Endian和Little Endian》一文中談了字節(jié)序的問題,原文見上面的超級(jí)鏈接?墒怯信笥讶匀粫(huì)問,CPU存儲(chǔ)一個(gè)字節(jié)的數(shù)據(jù)時(shí)其字節(jié)內(nèi)的8個(gè)比特之間的順序是否也有big endian和little endian之分?或者說是否有比特序的不同?
實(shí)際上,這個(gè)比特序是同樣存在的。下面以數(shù)字0xB4(10110100)用圖加以說明。
Big Endian
msb lsb
---------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Little Endian
lsb msb
---------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
實(shí)際上,由于CPU存儲(chǔ)數(shù)據(jù)操作的最小單位是一個(gè)字節(jié),其內(nèi)部的比特序是什么樣對(duì)我們的程序來說是一個(gè)黑盒子。也就是說,你給我一個(gè)指向0xB4這個(gè)數(shù)的指針,對(duì)于big endian方式的CPU來說,它是從左往右依次讀取這個(gè)數(shù)的8個(gè)比特;而對(duì)于little endian方式的CPU來說,則正好相反,是從右往左依次讀取這個(gè)數(shù)的8個(gè)比特。而我們的程序通過這個(gè)指針訪問后得到的數(shù)就是0xB4,字節(jié)內(nèi)部的比特序?qū)τ诔绦騺碚f是不可見的,其實(shí)這點(diǎn)對(duì)于單機(jī)上的字節(jié)序來說也是一樣的。
那可能有人又會(huì)問,如果是網(wǎng)絡(luò)傳輸呢?會(huì)不會(huì)出問題?是不是也要通過什么函數(shù)轉(zhuǎn)換一下比特序?嗯,這個(gè)問題提得很好。假設(shè)little endian方式的CPU要傳給big endian方式CPU一個(gè)字節(jié)的話,其本身在傳輸之前會(huì)在本地就讀出這個(gè)8比特的數(shù),然后再按照網(wǎng)絡(luò)字節(jié)序的順序來傳輸這8個(gè)比特,這樣的話到了接收端不會(huì)出現(xiàn)任何問題。而假如要傳輸一個(gè)32比特的數(shù)的話,由于這個(gè)數(shù)在littel endian方存儲(chǔ)時(shí)占了4個(gè)字節(jié),而網(wǎng)絡(luò)傳輸是以字節(jié)為單位進(jìn)行的,little endian方的CPU讀出第一個(gè)字節(jié)后發(fā)送,實(shí)際上這個(gè)字節(jié)是原數(shù)的LSB,到了接收方反倒成了MSB從而發(fā)生混亂。