perrynzhou

专注于系统组件研发

0%

关于CPU字节序的理解

为什么会有字节序这一说法

  • 对于单字节处理器不存在字节序,对于大于1个字节的位数的CPU,其寄存器的宽度也大于1个字节,所以存储字节排序的问题

大端字节序排序

  • 大端:高字节位在低地址存储,低字节位在高地址存储
  • 小端: 高字节位存储在高地址,低字节位存储在低地址
    1
    2
    3
    4
     例如 int  x = 0x0001,假设是在64位的CPU上,它的地址空间为:0xff13,其字节排序可能有两种可能:
    oxff13: 0 0 0 1 --->第一种情况 大端
    0xff13: 1 0 0 0 --->第二种情况 小端
    在x这个值中0001从左往右是高字节位到低字节位,也就是 0,0 是高字节,0 1 是低字节位。

    如何验证CPU的字节序呢?

  • C语言中有union结构,这个结构的数据存储是从低地址向高地址依次存储值,可以通过这个特性来验证CPU的字节序
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    /*************************************************************************
    > File Name: byte_order.c
    > Author:perrynzhou
    > Mail:perrynzhou@gmail.com
    > Created Time: Fri 15 Nov 2019 03:42:37 PM CST
    ************************************************************************/

    #include <stdio.h>
    typedef union object_t {
    int a;
    char b;
    } object;
    enum
    {
    big_endian_type = 0,
    small_endian_type,
    };
    int checkCpu(object *obj)
    {
    return obj->b == 1 ? small_endian_type : big_endian_type;
    }
    int main()
    {
    int v = 0x0001;
    object obj;
    obj.a = v;
    fprintf(stdout, "value:%d,value_string:%s,object address:%p\n", v, "0x0001", &obj);
    if (checkCpu(&obj) == big_endian_type)
    {
    fprintf(stdout, "store plan: |%d|%d|%d|%d|,big endian\n", 0, 0, 0, 1);
    }
    else
    {
    fprintf(stdout, "store plan: |%d|%d|%d|%d|,small endian\n", 1, 0, 0, 0);
    }
    return 0;
    }
    1
    2
    3
    4
    [perrynzhou@localhost ~/Source/vivo/linux_kernel_study/chapter_01]$ ./test 
    value:1,value_string:0x0001,object address:0x7ffcaf058a08
    store plan: |0|0|0|1|,big endian
    [perrynzhou@localhost ~/Source/vivo/linux_kernel_study/chapter_01]$