• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Welcome to ErranLi's Blog!

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              106 Posts :: 1 Stories :: 97 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(12)

            搜索

            •  

            積分與排名

            • 積分 - 174947
            • 排名 - 151

            最新評論

            閱讀排行榜

            原文:http://dev.csdn.net/article/39/39864.shtm

            ?Little Endian & Big Endian????

            這個標題中的Endian是什么意思呢?還是讓我們先來看看下面的情況,這是內(nèi)存中一個WORD值中的內(nèi)容,那么這個WORD中的值是0x1234呢,還是0x3412???

            low?byte?high?byte?
            0x12????? 0x34?

            熟悉x86匯編的人立刻就知道這個值應為0x3412,很對,但在一些情況下,比如說你在SGI的機器上看到這種情況,則正好相反,0x1234才是正確答案,這與CPU內(nèi)部處理數(shù)據(jù)的方式有關。這兩種處理方式都存在于不同廠商生產(chǎn)的CPU之中,在上例中若此WORD值為0x3412的,我們稱之為little-endian,?若為0x1234的,我們稱之為big-endian,這是兩種不同的byte?orders。MSDN中有比較精確的定義如下:

            Byte?Ordering?Byte?ordering?Meaning?
            big-endian?The?most?significant?byte?is?on?the?left?end?of?a?word.?
            little-endian?The?most?significant?byte?is?on?the?right?end?of?a?word.?

            一般來說我們不用關心byte?ordering的問題,但若要涉及跨平臺之間的通信和資源共享,則不得不考慮這個問題了。也許你會說,我永遠不會去用其它非x86的CPU,也許是這樣,你甚至可以不必知道我們最常用的Intel,AMD等生產(chǎn)的x86的byte?ordering是little-endian的,而且按現(xiàn)在的裝機數(shù)量來看,可以說世界上絕大多數(shù)CPU是little-endian的,但多了解一些沒有什么壞處,也許有用上的一天,實際若您要涉及到網(wǎng)絡編程,了解一些還是有所幫助的,看完本文后您就應該知道為何socket編程中為何要用到如?ntohl,?htonl,?ntohs,?htons這幾個看起來名字似乎怪怪的API了,也很容易理解這些函數(shù)名的意義了。

            假設我們要在不同byte?ordering的機器之間傳輸和交換數(shù)據(jù),那該怎么辦呢,有兩個方法,一是全部轉(zhuǎn)換成文本來傳輸(如XML使用的),另一個方法兩方都按照某一方的byte?order,這時就涉及到了不同byte?order之間相互轉(zhuǎn)換的問題(網(wǎng)絡傳輸標準如TCP/IP采用第二種方法并且由于歷史的原因,byte?ordering是big-endian的)。兩種之間該如何轉(zhuǎn)換呢?方法有很多,我們可以先看看MFC中在處理serialize的代碼中所用的方法(List),?雖然代碼應該是高效易讀的,?但我個人并不喜歡它,?原因是我覺得這不是一種通用優(yōu)美的方法.下面列出的是我自己寫的轉(zhuǎn)換的代碼:

            template
            F3D_INLINE?T ConvertEndian(T??t)
            {?
            ???T tResult?=?0;?
            ???for?(int??I?=?0;?I?<?sizeof(T);?++?I)?
            ???{?
            ??????tResult?<<=?8;????
            ??????tResult?|=?(t?&?0xFF)?;?

            ??????t?>>=?8;?
            ???}?
            ???return??tResult;
            }

            原理非常簡單,交換字節(jié)順序,我就不多說了,當然這個寫法并不是快速的,?只是通用的(我沒條件試,?若有不對之處請指出),?若要快速的代碼,可以在不同platform上用與platform相關的代碼,?如在PowerPC上有?"load?word?byte-reversed?indexed"?(lwbrx)?和?"load?halfword?byte-reversed?indexed"?(lhbrx)?指令,?在x86上還可用BSWAP單個匯編指令等,在類型上專為int16,?int32寫的通用的代碼也可以比這快得多.?

            當然如果在byte?ordering相同的情況下,應該不必用這個轉(zhuǎn)換函數(shù),所以我們可以定義一個宏來處理不同的byte?ordering,也可以在運行時測試byte?ordering,?下面的代碼給出了一個簡單的測試方法。?


            //?Test?for?endianness.
            F3D_INLINE?bool IsLittleEndian(void)
            {?
            ???DWORD dwTestValue?=?0x12345678L;?
            ???return??(*((BYTE*)&dwTestValue)?==?0x78);
            }

            但是float比較怪,有可能所涉及到不僅僅是byte?order的問題,因為有些平臺如Alpha不使用IEEE的浮點格式,還得自己轉(zhuǎn)換。當然同上,其它的方法一是將所用的float用文本方式輸入輸出,另一個辦法是在某些情況下可將其轉(zhuǎn)換成定點數(shù)再處理,這里我不再深入。

            如果是讀寫第三方已經(jīng)指定byte?order的文件或數(shù)據(jù)流,比如說讀SGI的位圖文件格式,則可以直接自行按指定的byte?order拼起來,不必考慮host機是何種byte?ordering。下面我給出相應的代碼:


            //?Read?a?little-endian?TYPE?from?address
            template
            F3D_INLINE?T GetLittleEndian(const?BYTE*??pBuf)
            {?
            ???T tResult?=?0;?
            ???pBuf?+=?sizeof(T)?-?1;?
            ???for?(int??I?=?0;?I?<?sizeof(T);?++?I)?
            ???{?
            ??????tResult?<<=?8;?
            ??????tResult?|=?*pBuf?--;?
            ???}?

            ???return??tResult;
            }

            //?Read?a?big-endian?TYPE?from?address
            template
            F3D_INLINE?T GetBigEndian(const?BYTE*??pBuf)
            {?
            ???T tResult?=?0;?
            ???for?(int??I?=?0;?I?<?sizeof(T);?++?I)?
            ???{?
            ??????tResult?<<=?8;?
            ??????tResult?|=?*pBuf?++;?
            ???}?

            ???return??tResult;
            }

            //?Set?a?little-endian?TYPE?on?a?address
            template
            F3D_INLINE?void SetLittleEndian(BYTE*??pBuf,?T??t)
            {?
            ???for?(int??I?=?0;?I?<?sizeof(T);?++?I)?
            ???{?
            ???*pBuf?++?=?BYTE(t?&?0xFF);?
            ???t?>>=?8;?
            ???}
            }

            //?Set?a?big-endian?T?on?a?address
            template
            F3D_INLINE?void SetBigEndian(BYTE*??pBuf,?T??t)
            {?
            ???pBuf?+=?sizeof(T)?-?1;?
            ???for?(int??I?=?0;?I?<?sizeof(T);?++?I)?
            ???{?
            ??????*pBuf?--?=?BYTE(t?&?0xFF);?
            ??????t?>>=?8;?
            ???}
            }

            從上文可以看出,byte?order挺簡單的,一般應用中可能也用不上,但若您對寫跨平臺的程序有興趣,則一定要了解的比較清楚才行。以上代碼都是從實際使用的源碼中取下來的。?

            附:常見Processor,?OS的byte?ordering情況

            Processor?OS?Order?
            x86?(Intel,?AMD,?…?)?All?little-endian?
            DEC?Alpha?All?little-endian?
            HP-PA?NT?little-endian?
            HP-PA?UNIX?big-endian?
            SUN?SPARC?All??big-endian?
            MIPS?NT?little-endian?
            MIPS?UNIX?big-endian?
            PowerPC?NT?little-endian?
            PowerPC?non-NT?big-endian?
            RS/6000?UNIX?big-endian?
            Motorola?m68k?All?big-endian?

            posted on 2007-10-13 16:23 erran 閱讀(5316) 評論(0)  編輯 收藏 引用 所屬分類: C & C++
            四虎国产精品免费久久久| 久久WWW免费人成一看片| 精品久久一区二区| 久久精品国产亚洲7777| 久久91精品国产91| 久久久久免费精品国产| 久久亚洲AV无码西西人体| 久久久久久久亚洲Av无码| 99久久国产免费福利| 欧美一区二区久久精品| 久久免费国产精品一区二区| 一本久久精品一区二区| 久久九九青青国产精品| 2020国产成人久久精品| 国产毛片久久久久久国产毛片 | 新狼窝色AV性久久久久久| 久久99精品国产麻豆宅宅| 久久这里只有精品视频99| 国产99久久精品一区二区| 欧美亚洲国产精品久久| 国产69精品久久久久99尤物| 人妻精品久久久久中文字幕69 | 99久久国产亚洲高清观看2024| 国内精品久久国产| 久久99精品久久久久久齐齐| 国产精品久久影院| 色偷偷偷久久伊人大杳蕉| 一本色综合网久久| 一本色道久久综合| 亚洲午夜无码AV毛片久久| 久久久综合香蕉尹人综合网| 久久精品国产精品青草app| 久久久久人妻一区精品色| 亚洲国产精品高清久久久| 精品无码久久久久国产动漫3d| 久久久噜噜噜久久中文字幕色伊伊| 丰满少妇人妻久久久久久4| 99热热久久这里只有精品68| 丁香久久婷婷国产午夜视频| 久久夜色精品国产亚洲| 国内精品久久久久久麻豆|