关于CPU的大小端存储模式

关于CPU的大小端存储模式


1. 决定因素

CPU是大小端存储的决定因素,编译器和操作系统仅仅是为了适配CPU。

 

2. CPU为什么会有大小端存储模式

在计算机中,数据存储的基本单位(也叫最小单位)是字节,每个存储单元(一个地址单元)上可以存储一个字节的数据。以C语言为例,char类型的数据就是一个字节,但是其他的数据类型就不止一个字节,比如int类型的数据是4个字节,short类型(short int)是2字节,long类型(long int)是8/4字节(与编译器的数据模型相关),long long数据类型有8字节……。也就是说,当一个数据大于8个bit的时候,CPU要如何进行存储。

可以认为内存地址是有序递增的(低地址到高地址),所以进行数据存储的时候无非就两种情况,低地址上放低字节数据还是放高字节数据。

 

3. 大小端存储模式的概念

大端模式(Big Endian):数据的高字节存储在内存的低地址中

小端模式(Little Endian):数据的高字节存储在内存的高地址中

例子:CPU/MCU 存储一个整型数据 int data = 305419896 (int类型的最大值是4294967295)

    为了形象一点,先将10进制数据转成16进制,即305419896D = 12345678H。对于数据0x12345678来说,高字节数据到低字节数据分别是:0x12、 0x34、 0x56、 0x78,总共是4个字节。

(1)如果CPU是大端模式,则数据存储如下图。

假设存储的起始地址为0x00001f00,则存储4字节需要用到4个连续的地址单元,地址单元和地址上存储的字节数据对应如下:

Address           Data

0x00001f00     0x12

0x00001f01     0x34

0x00001f02     0x56

0x00001f03     0x78

细分到0/1存储:

Address:  0x00001f00      0x00001f01    0x00001f02    0x00001f03

Data :      0001 0010       0011 0100     0101 0110      0111 1000

 

(2)如果CPU是小端模式,则数据存储如下图。

假设存储的起始地址为0x00001f00,则存储4字节需要用到4个连续的地址单元,地址单元和地址上存储的字节数据如下:

Address          Data

0x00001f00     0x78

0x00001f01     0x56

0x00001f02     0x34

0x00001f03     0x12

细分到0/1存储:

Address:  0x00001f00      0x00001f01    0x00001f02    0x00001f03

Data :      0111 1000         0101 0110     0011 0100      0001 0010

 

4. 判断方法

方法1:使用共用体

共用体中的所有数据成员共用同一块内存(连续的多个单元),即各个数据成员存储的起始地址相同。

测试程序如下:

union cpu_mode

         {

                   int a;  /*4 byte*/

                   char b; /*1 byte*/

                   char c; /*1 byte*/

                   char d; /*1 byte*/

                   char e; /*1 byte*/

         } pri_data;

         pri_data.a = 1;

         printk("pri_data.a = %d\n", pri_data.a);

 

         printk("pri_data.b = %d\n", pri_data.b);

         printk("pri_data.c = %d\n", pri_data.c);

         printk("pri_data.d = %d\n", pri_data.d);

         printk("pri_data.e = %d\n", pri_data.e);

 

         if (1 == pri_data.b == pri_data.c == pri_data.d == pri_data.e) {

                   printk("小端存储模式\n");

         } else {

                   printk("大端存储模式\n");

         }

对于数据成员a,值为0x00 00 00 01,如果CPU是小端模式,则低地址上存储的值应该是0x01,读共用体的其他数据成员的值就应该读到1;反之,如果CPU是大端模式,则低地址上存储的就是0x00,其他数据成员的值应该是0。

 

方法2:直接读取内存地址上的值,测试程序如下。

         unsigned short pri_data=0xaabb;

 

         char data1,data2;

 

         data1 = *((char*)&pri_data); //低地址单元上的数据

         data2 = *((char*)&pri_data + 1); //高地址单元上的数据

 

         printk("data1 = 0x%02x\n", data1);

         printk("data2 = 0x%02x\n", data2);

 

         if (data1 == 0xbb && data2 == 0xaa) {

                   printk("小端存储模式\n");

 

         } else if (data1 == 0xaa && data2 == 0xbb) {

                   printk("大端存储模式\n");

 

         } else {

                   printk("未知存储模式\n");

 

         }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值