little endian & big endian

    技术2022-07-05  137

    little endian和big endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度

     

    跨越多个字节的数据的存放形式. 

            假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内

     

    存顺序的机器上从字节的角度去看的话分别表示为: 

           1)little endian:在内存中的存放顺序是0x00000000-0xcd,0x00000001-

     

    0xab,0x00000002-0x34,0x00000003-0x12 

           2)big  endian:在内存中的存放顺序是0x00000000-0x12,0x00000001-

     

    0x34,0x00000002-0xab,0x00000003-0xcd 

           需要特别说明的是,以上假设机器是每个内存单元以8位即一个字节为单位的. 

           简单的说,ittle endian把低字节存放在内存的低位;而big endian将低字节存放在

     

    内存的高位. 

           现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系

     

    列的CPU采用的是big endian. 

     

           以下是判断字节存储顺序的可移植的C语言代码: 

     

     

    #include <stdio.h>

     

     

     

    union

     

    {

     

    long Long;

     

    char Char[sizeof(long)];

     

    }u;

     

     

     

    int main()

     

    {

     

    u.Long = 1;

     

     

     

    if (u.Char[0] == 1)

     

    {

     

    printf("Little Endian!/n");

     

    }

     

    else if (u.Char[sizeof(long) - 1] == 1)

     

    {

     

    printf("Big Endian!/n");

     

    }

     

    else

     

    {

     

    printf("Unknown Addressing!/n");

     

    }

     

     

     

        printf("Now, Let's look at every byte in the memory!/n");

     

        for (int i = 0; i < sizeof(long); ++i)

     

        {

     

            printf("[%x] = %x/n", &u.Char, u.Char);

     

        }

     

     

     

    return 0;

     

    }

     

     

     

     很多人认为掌握这个知识是不必要,其实不然.在网络编程中,TCP/IP统一采用big endian方

     

    式传送数据,也就是说,假设现在是在一个字节顺序是little endian的机器上传送数据,要求

     

    传送的数据是0XCEFABOBO,那么你就要以0XBOBOFACE的顺序在unsigned int中存放这个数据,

     

    只有这样才能保证存放的顺序满足TCP/IP的字节顺序要求.很多时候,需要自己编写应用层的

     

    协议,字节顺序的概念在这个时候就显得及其的重要了. 

           下面给出的是在big endian和little endian中相互转换的代码,C语言强大的位操作

     

    的能力在这里显示了出来: 

     

     

    #include <stdio.h>

     

     

     

    const unsigned char SIZE_OF_UNSIGNEDINT  = sizeof(unsigned int);

     

    const unsigned char SIZE_OF_UNSIGNEDCHAR = sizeof(unsigned char);

     

     

     

    void put_32(unsigned char *cmd, unsigned int data)

     

    {

     

        int i;

     

        for (i = SIZE_OF_UNSIGNEDINT - 1; i >= 0; --i)

     

        {

     

            cmd = data % 256;

     

            // 或者可以:

     

            //cmd = data & 0xFF;

     

            data = data >> 8;

     

        }

     

    }

     

     

     

    unsigned int get_32(unsigned char *cmd)

     

    {

     

        unsigned int  ret;

     

        int i;

     

     

     

        for (ret = 0, i = SIZE_OF_UNSIGNEDINT - 1; i >= 0; --i)

     

        {

     

            ret  = ret << 8;

     

            ret |= cmd;        

     

        }

     

     

     

        return ret;

     

    }

     

     

     

    int main(void)

     

    {

     

        unsigned char cmd[SIZE_OF_UNSIGNEDINT];

     

        unsigned int data, ret;

     

        unsigned char *p;

     

        int i;

     

     

     

        data = 0x12345678;

     

        printf("data = %x/n", data);

     

        // 以字节为单位打印出数据

     

        p = (unsigned char*)(&data);

     

        for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i)

     

        {

     

            printf("%x", *p++);

     

        }

     

        printf("/n");

     

     

     

        // 以相反的顺序存放到cmd之中

     

        put_32(cmd, data);

     

        for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i)

     

        {

     

            printf("cmd[%d] = %x/n", i, cmd);

     

        }

     

     

     

        // 再以相反的顺序保存数据到ret中

     

        // 保存之后的ret数值应该与data相同

     

        ret = get_32(cmd);

     

        printf("ret = %x/n", ret);

     

        p = (unsigned char*)(&ret);

     

        for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i)

     

        {

     

            printf("%x", *p++);

     

        }

     

        printf("/n");

     

     

     

        return 0;

     

    }


    最新回复(0)