<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 閱讀(683) 評論(0)  編輯  收藏 所屬分類: cppZZ
    主站蜘蛛池模板: 国产成人亚洲合集青青草原精品| 无码日韩精品一区二区三区免费 | 亚洲高清不卡视频| 国产中文字幕免费观看| 精品久久久久成人码免费动漫| 免费无码H肉动漫在线观看麻豆| 色欲aⅴ亚洲情无码AV蜜桃| 久久精品国产99国产精品亚洲| 图图资源网亚洲综合网站| 国产乱辈通伦影片在线播放亚洲| 在线jlzzjlzz免费播放| 99视频全部免费精品全部四虎| 暖暖免费日本在线中文| 在线视频网址免费播放| 免费高清A级毛片在线播放| 亚洲aⅴ无码专区在线观看 | 久久午夜免费视频| 蜜桃AV无码免费看永久| 久久久久国产精品免费网站| 91免费国产视频| 中文字幕在线视频免费| 国产日韩精品无码区免费专区国产 | 亚洲久悠悠色悠在线播放| 亚洲精品日韩中文字幕久久久| 亚洲视频中文字幕| 久久国产亚洲观看| 亚洲AV无码久久寂寞少妇| 亚洲国产精品一区二区第一页| 亚洲区小说区激情区图片区| 怡红院亚洲怡红院首页| 国产午夜亚洲不卡| 国产AV无码专区亚洲AWWW| 中文字幕第一页亚洲| 亚洲人成图片小说网站| 国产亚洲一区二区手机在线观看| 亚洲国产无套无码av电影| 久久亚洲精品成人777大小说| 亚洲视频在线观看免费| 亚洲制服在线观看| 亚洲愉拍一区二区三区| 午夜亚洲WWW湿好爽|