专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

MSP430中内存分配不连续的问题

作者:佚名   来源:学会珍惜LW的博客   点击数:  更新时间:2014年08月28日   【字体:

      今天发现了一个挺奇怪的问题,就是在430的RAM中,想给连续的内存地址分配一个char型和一个int型变量时,两个变量之间的地址会跳一个。具体情况看下图。

 



           从上图可以看到,第一根红线表面一个unsigned char型变量的值为108,地址为0x472A,占一个字节;紧接着下一个为unsigned char型变量,其值为2,地址为0x472C,占两个字节。那0x472B这个地址哪儿去了呢?我们可以看到,在存一个char型变量,后面接一个int型变量时,中间会有一个地址被跳过去;

        类似的情况还出现在char型变量后面存一个long int型变量时,但是int型变量和long int型变量连续存,或者单独的char型变量连续存,以及单独的int或long int连续存时,均不存在这个问题。

        这个挺奇怪的……这对于SD卡参数的解析会有很大影响。可能是跟编译器有关,这里我用的是CCS V5.4。等找到解决方案之后,再在后文补上。

 

**********************************************************************************************************

         晚上请教了znFAT群里的“少数派”大哥之后,获得了问题的答案,很开心~这里与大家分享一下。

       出现这个问题的原因是结构体的对齐问题。简单地说,就是char型变量的地址是任意的;但是int型变量由于要占2个字节,为了提高CPU的访问速度,所以其首地址必须要为偶数;long int型占4个字节,其首地址必须要为4的倍数。

       关于这个问题再具体的讲解,我摘录了david0421的博文“单片机结构体内存的分配 ”中的一段话,他博文的原始地址在http://bibber.blog.sohu.com/230549556.html。

博文如下:

什么是字节对齐
     一个变量占用 n 个字节,则该变量的起始地址必须能够被 n 整除,即: 存放起始地址 % n = 0, 对于结构体而言,这个 n 取其成员种的数据类型占空间的值最大的那个。
为什么要字节对齐
    内存空间是按照字节来划分的,从理论上说对内存空间的访问可以从任何地址开始,但是在实际上不同架构的CPU为了提高访问内存的速度,就规定了对于某些类型的数据只能从特定的起始位置开始访问。这样就决定了各种数据类型只能按照相应的规则在内存空间中存放,而不能一个接一个的顺序排列。

    举个例子,比如有些平台访问内存地址都从偶数地址开始,对于一个int型(假设32位系统),如果从偶数地址开始的地方存放,这样一个读周期就可以读出这个int数据,但是如果从奇数地址开始的地址存放,就需要两个读周期,并对两次读出的结果的高低字节进行拼凑才能得到这个int数据,这样明显降低了读取的效率。

          根据这个原理,我利用CCS在MSP430F6638上做了一个简单的测试。

        首先定义了两个char型变量和一个int型变量,其内存分配如下如所示。我们可以看到,此时int型变量的首地址为偶数,内存分配是连续的。



           然后我只定义一个char型变量和一个int型变量,其内存分配如下图所示,我们可以看到,不连续了。因为int型变量的首地址必须问偶数,所以跳了一个字节。



           感谢“少数派”大哥的点拨~

关闭窗口