zoukankan      html  css  js  c++  java
  • 字节内存储顺序

      source address : http://www.linuxjournal.com/article/6788?page=0,1 

      1.Byte Order: the Endianness

      Two types of endianness exist, big endian and little endian. Big endian refers to the method that stores the most significant byte of an integer at the lowest byte address. Little endian is the opposite; it refers to the method of storing the most significant byte of an integer at the highest byte address.

      Bit order usually follows the same endianness as the byte order for a given computer system. That is, in a big endian system the most significant bit is stored at the lowest bit address; in a little endian system, the least significant bit is stored at the lowest bit address.

      2.Endianness of Bus

      The bus we refer to here is the external bus we showed in the figure above. We use PCI as an example below. The bus, as we know, is an intermediary component that interconnects CPUs, devices and various other components on the system. The endianness of bus is a standard for byte/bit order that bus protocol defines and with which other components comply.

      Take an example of the PCI bus known as little endian. It implies the following: among the 32 address/data bus line AD [31:0], it expects a 32-bit device and connects its most significant data line to AD31 and least significant data line to AD0. A big endian bus protocol would be the opposite.

      For a partial word device connected to bus, for example, an 8-bit device, little endian bus-like PCI specifies that the eight data lines of the device be connected to AD[7:0]. For a big endian bus protocol, it would be connected to AD[24:31].

      In addition, for PCI bus the protocol requires each PCI device to implement a configuration space. This is a set of configuration registers that have the same byte order as the bus.

          3.Endianness of Network Protocols

      The endianness of network protocols defines the order in which the bits and bytes of an integer field of a network protocol header are sent and received. We also introduce a term called wire address here. A lower wire address bit or byte always is transmitted and received in front of a higher wire address bit or byte.

      The endianness of NIC devices usually follow the endianness of the network protocols they support, so it could be different from the endianness of the CPU on the system. Most network protocols are big endian;
      

      4. bit field and memory storage
    ex:

    typedef struct {
        unsigned int    b1:1;
        unsigned int    b2:8;
        unsigned int    b3:7;
        unsigned int    b4:8;
        unsigned int    b5:7;
        unsigned int    b6:1;} BIT_STRUCT;

          Suppose you wanted to use the same structure definition to read in bit field data on an big endian

    and little endian machine and you were willing to massage the data on input before mapping the structure

    to it. Suppose we started with big endian data that was 32 bits long.


    Memory layout big/little endian:

    Let the start of memory be adressed as below for a big endian machine...

                  byte 0          byte 1       byte 2       byte 3

      • |B31....B25     |B24....B16         |B15....B8   |B7....B0           |   Big endian
      • |B7....B0         ||B15....B8          ||B24....B16||B31....B25      |   Little endian
      • |b1[0],b2[7:1] | b2[0], b3[6:0]   | b4[7:0]       | b5[6:0] , b6[0]| physical layout when bigend generates.

      总结上面几点:

        通常来说,对于big endian machine,它的字节序与比特序都是大端,即低地址存高位字节,bit0存高位二进制码;

    现举一个例子,比特域顺序是从左到右存   

    ex:

    union {
      struct {
       unsigned char a:1;
       unsigned char b:3;
       unsigned char c:2;
       }s;
      unsigned char x;
     }tb;
     tb.x = 0;
     tb.s.a = 0;
     tb.s.b = 2;
     tb.s.c = 1;   
    
     tb.x = ?
    left -- > right
    b0 b1 b1 b3 b4 b5 b6 b7

     so
        little-endian bitfield: ascending order in byte(left to right) 

     tb.x = 0 010 10 00 = bin(0001 0100) = 0x14 = 20
            0  2   1 padding

        big-endian bitfield : descending order in byte (right to left)

     tb.x = 0 010 01 00 = bin(0010 0100)=0x24 = 36
            0 2  1 padding

      test result:
         avr32 studio(黑色甲壳虫icon) :

    big-endian bitfield : tb.x = 36

         linux gcc:

    little-endian bitfield :  tb.x = 20

        avr atmel studio 6.0:

    little-endian bitfield :  tb.x = 20

     another example:

    typedef struct
            {
                byte                      ndd_p          : 4;
                byte                      ndd_net           : 4;
                word                      pref_field    : 9;
                word                      sbits            : 3;
                word                      pref_field_length : 4;
            } s;
        
        s stru;
        stru.ndd_p = 2;                            0010
        stru.ndd_net = 1;                          0001
        stru.pref_field = 0x187;                   1 1000 0111
        stru.sbits = 2;                            010
        stru.pref_field_length = 0x06;             0110

    little endian machine:

    |<--                  32                    -->|
    |<-- 8 -->| byte align|<-  9  ->| |<-3->||<-4->|
    0100 1000 0000 0000 1110 0001 1 010 0110 ndd_p ndd_net padding pref_field sbits len 0001 0010 0000 0000 1000 0111 0110 0101 0x 12 00 87 65
       b0 ... b7

    big endian machine:

    |<--                  32                    -->|
    |<-- 8 -->|           |<-  9  ->| |<-3->||<-4->|
    0010 0001 0000 0000 1 1000 0111 010 0110 ndd_p ndd_net padding pref_field sbits len 0010 0001  0000 0000 1100 0011 1010 0110 0x 21 00 c3 a6
       b0 ... b7

    另一种理解方式,比较直观

    b7 ... b0 b7 ... b0 ...
    byte 0        byte 1      byte 2     byte 3
    b31 ... b24 b23 ... b16 b15 ... b8 b7 ... b0      big endian
    b7 ... b0   b15 ... b8 b23 ... b16 b31 ... b24    little endian
    |<--                           32                          -->|
    |<-- 8 -->|              |<-   9   ->|           |<-3->||<-4->|
     0010 0001     0000 0000 1 1000 011  1             010   0110    big endian
     ndd_p ndd_net  padding field_high8 field_low1     sbits  len
     0010 0001  0000 0000  1100 0011  1010 0110
     0x   21       00         c3         a6    
                                                                     big endian member layout : from high bit end to low bit end  -> b31 to b0
    
     0001 0010   0000 0000  1000 0111 0110  010     1                little endian
    ndd_net ndd_p paddind  field_low8 len  sbits field_high1 0x
    12 00 87 65 little endian member layout : from low to high -> b0 to b31 high -- > low 其它共同点:高bit位存高位值,不因大小端改变而变

     附

     
    // bit_fields1.cpp
    struct Date
    {
       unsigned nWeekDay  : 3;    // 0..7   (3 bits)
       unsigned nMonthDay : 6;    // 0..31  (6 bits)
       unsigned nMonth    : 5;    // 0..12  (5 bits)
       unsigned nYear     : 8;    // 0..100 (8 bits)
    };
    
    int main()
    {
    }
    

    The conceptual memory layout of an object of type Date is shown in the following figure.

    Memory Layout of Date Object

    Note that nYear is 8 bits long and would overflow the word boundary of the declared type, unsigned int. Therefore, it is begun at the beginning of a new unsigned int. It is not necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration.

    Microsoft Specific

    The ordering of data declared as bit fields is from low to high bit, as shown in the figure above.

    END Microsoft Specific

    If the declaration of a structure includes an unnamed field of length 0, as shown in the following example,

     
    // bit_fields2.cpp
    struct Date
    {
       unsigned nWeekDay  : 3;    // 0..7   (3 bits)
       unsigned nMonthDay : 6;    // 0..31  (6 bits)
       unsigned           : 0;    // Force alignment to next boundary.
       unsigned nMonth    : 5;    // 0..12  (5 bits)
       unsigned nYear     : 8;    // 0..100 (8 bits)
    };
    
    int main()
    {
    }
    

    the memory layout is as shown in the following figure.

    Layout of Date Object with Zero-Length Bit Field

  • 相关阅读:
    Silverlight 2中实现文件上传和电子邮件发送
    Silverlight结合Web Service进行文件上传
    silverlight DataGrid 内嵌ComboBox 实现加载和保存
    silverlight 使用IValueConverter 转换
    检测场所条件查询
    代码中的坏味道
    Prism初研究之Bootstrapper
    Prism初研究之简介
    编写可读代码的艺术
    ffmpeg怎么样处理网络流
  • 原文地址:https://www.cnblogs.com/lovemo1314/p/3066910.html
Copyright © 2011-2022 走看看