<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://m.tkk7.com/Files/jinfeng_wang/Endian.rar


    Endian 
    介紹

    1.       Endian簡介

    Endian可以看作是系統的一種屬性, 它指示多字節整數是從左向右放, 還是從右向左放. 它有兩種形式:

    ?           Big Endian

    ?           Little Endian

     

    BE把多字節整數的MSB(Most Significant Byte)存儲在最低的地址上, LSB(Least Significant Byte)順序存放在最高的地址上, LE正好相反.

     

    4-bytes數據0x01020304以兩種不同的方式存儲如下:

    00000001 00000010 00000011 00000100

    Address

    00

    01

    02

    03

    Big-Endian

    00000001

    00000010

    00000011

    00000100

    Little-Endian

    00000100

    00000011

    00000010

    00000001

     

    所有的處理器必須指定它用Big Endian還是Little Endian. Intel's 80x86 processor

    little endian. Sun's SPARC, Motorola's 68K, PowerPC系列是big endian. 有些處理器甚至設置了一個標志位可以選擇所需要的Endian.

     

    2.       出現的問題

    如果我們不了解Endian在數據存儲上的差異, 使用的時候就有可能出現問題, 比如我們想要的是0x01020304,但是在little endian的情況下, 就有可能得到0x04030201.

    如何避免錯誤的數據呢? 首先先看一下系統是如何存取數據的.


    下面是同一組數據在兩種endian下的memory dump:

    char              c1 = 1;
    char       c2 = 2;
    short     s  = 255; // 0x00ff
    long       l  = 0x11223344;

    Offset    :      Memory dump
    0x0000 :    
    01 02 00 FF
    0x0004 :     11 22 33 44

    A Big-Endian memory dump

     

    char              c1 = 1;
    char       c2 = 2;
    short     s  = 255; // 0x00ff
    long       l  = 0x11223344;

    Offset    :      Memory dump
    0x0000 :    
    01 02 FF 00
    0x0004 :     44 33 22 11

    A Little-Endian memory dump

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


    上圖表示了數據的存放方式, 雖然s, l在兩種endina下的存儲方式不同, 但取出s, l的時候系統還是會還原成原來的值, 數據是不會改變的. 就是說平常使用的過程中, 我們不必關心這種存取的過程.

     

    那么在什么情況下會造成數值的改變呢? 我們從存數據和取數據兩個方面進行說明

    2.1.      存數據

    有一些接口和規范規定了必須以某種Endian的格式進行通訊, 大多數都規定以Big Endian的格式. 比如SCSI command數據的傳輸, TCP/IP網絡協議等.

          

           下面是10 字節的Read command, CDB格式如下:

    Bit

    Byte

    Operation Code (28h)

    1

    Reserved

    ( 0 0 0 )b

    DPO

    FUA

    ( 0 )b

    Reserved

    ( 0 0 0 )b

    RelAdr ( 0 )b

    (MSB)

    LBA

     

    (LSB)

    Reserved  ( 00 h)

    (MSB)                                                         

     Transfer Length                        (LSB)

    Controller

     

     

    我們定義如下的結構體填充.

    typedef struct cdb1tag

    {

                  uchar_t         opcode;

                  uchar_t         lun;

                  uint_t           lba;

                  uchar_t         rsv1;

                  ushort_t     block;

                  uchar_t         cntl;

    } CDB1;

     

    假設要發行一個Read操作, LBA0x01020304. Transfer Length255(0x00ff).

    我們需要對CDB進行填充. 賦值:

    lba=0x01020304;              block=0x00ff;      …(其他參數不討論)

     

    下面我們看看賦值后Big EndianLittle Endian是怎樣存儲這段數據的:

     

    Byte

    (BIG_ENDIAN)

    0

     

    1

     

    (MSB)    01

    02

    03

    04    (LSB)

    6

     

    (MSB)    00            

              ff    (LSB)

    9

     

    Byte

    (LITTLE_ENDIAN)

    0

     

    1

     

    (LSB)    04

    03

    02

    01    (MSB)

    6

     

    (LSB)     ff

              00    (MSB)

    9

     

     

     

     


    2.2.      取數據

    同上面講到的, 如果規定了必須以某種Endian通訊, 則必須按照規定的順序把數據取出來, 這種情況同存數據的例子, 只不過一個是存, 一個是取.

     

    union{

    char  c_num[4]; // 01 02 03 04
    int i_num;

    }dev;

    Offset    :      Memory dump

    0x0000 :     01 02 03 04

    i_num=  0x04030201 (LE)  :  0x01020304 (BE)

    另外, 不按照系統存儲的方式取數據, 有時會發生意外. 比如說我們是以一個字節一個字節存儲的數據, 卻以4個字節為一組取出.

     

     

     

     

     

     

    不過有的數據比較特殊, 即使顛倒字節順序,  數值也不發生改變

    例如:     0  0x1111  0x01020201

     

    3.       解決方法

    ?           多字節數據以單字節寫入/讀出

    IN:

    (unsigned char)((lba & 0Xff000000) >> 24)  à MSB

    (unsigned char)((lba & 0X00ff0000) >> 16)

    (unsigned char)((lba & 0X0000ff00) >> 8)

    (unsigned char) (lba & 0X000000ff)                à LSB

    OUT:

    endian_dump()

     

    ?           交換字節 byte_swap()

     

    posted on 2007-05-28 15:08 jinfeng_wang 閱讀(685) 評論(0)  編輯  收藏 所屬分類: cppZZ
    主站蜘蛛池模板: 亚洲国产成人久久综合一区| 国产精品区免费视频| 蜜桃AV无码免费看永久| 老牛精品亚洲成av人片| 亚洲国产精品成人精品软件| 亚洲人成人77777网站| 免费在线观看黄网| 毛片免费全部播放一级| 18禁成人网站免费观看| 久久99免费视频| 男女一进一出抽搐免费视频| 亚洲国产精品无码专区| 亚洲AV中文无码乱人伦| 免费看搞黄视频网站| 国产高潮流白浆喷水免费A片 | 老牛精品亚洲成av人片| 亚洲成av人片在线天堂无| 精品久久亚洲中文无码| 亚洲国产精品成人精品软件| 亚洲精品韩国美女在线| 国产免费69成人精品视频| 免费观看一级毛片| 女人18毛片特级一级免费视频| 一级女人18毛片免费| 国产大片免费天天看| 一级毛片在线免费视频| 久青草国产免费观看| 一区免费在线观看| 永久免费精品影视网站| 亚洲一级片免费看| 国产一级黄片儿免费看| 两个人看的www免费视频| a级毛片毛片免费观看久潮 | 色老头永久免费网站| 99热精品在线免费观看| 在线观看的免费网站无遮挡 | 精品亚洲A∨无码一区二区三区| 亚洲va中文字幕无码久久| 久久久久无码精品亚洲日韩 | 一二三四免费观看在线电影| 国产免费一区二区三区免费视频 |