首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM数据对齐 ----- ADS1.2编译

ARM数据对齐 ----- ADS1.2编译

ARM数据对齐  -----  ADS1.2编译


一、
问题来源

且看下面一段代码:
char    buff[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xbc, 0xcd};
int      v32, *p32;
short   v16, *p16;
p32 = (int*)&( buff[1] );  
p16 = (short*)&( buff[1] );
v32 = *p32;
v16 = *p16;
我们来看看在ADS1.2编译后,执行的结果如下:
v32 = 0x12785634
v16 = 0x1234
不管数据模式是大端结构,还是小端结构,结果都不对。


二、分析原因
默认情况下,ADS编译器使用的是数据类型的自然边界对其方式。数据的自然对其方式是指:如果该数据类型是n个字节的,那么该数据类型就按n字节对齐。例如:
    1.Usigned char 1字节的,那么数据就按1字节对齐。
定义两个变量如下: usigned char  a08,b08;
如果a08所在的地址为,0x80000002,则b08所在的地址为0x80000003,两个变量是连续分配的。
    2Usigned short 2字节的,那么数据就按2字节对齐。

定义两个变量如下: usigned char   a08;

                           Usigned short  a16;

如果a08所在的地址为0x80000002,那么a16所在的地址为0x80000004a16不会分配到0x80000003,默认情况下,编译器为usigned short类型的变量分配到2的倍数的地址处。

    2usigned long 4字节的,那么数据就按4字节对齐。

定义两个变量如下: usigned char   a08;

                           Usigned long   a32

如果a08所在的地址为0x80000005,那么a16所在的地址为0x80000008a32不会分配到0x80000006,默认情况下,编译器为usigned long类型的变量分配到4的倍数的地址处。



三、解决办法

如果我们想要让编译器不使用自然边界对齐,让任何类型的变量都紧接着上一变量的地址进行分配,可以使用__packed关键字。


(未完)







四、使用__packed的注意事项
1__packed 对局部变量无效。
2、声明为__packed 的变量,必须使用__packed 的指针变量来指向其地址。

如:

      __packed  u16  u16a;
      __packed  u16  *pu16;
      pu16 = (u16 *)&u16a;
3、声明为__packed 的结构

声明为__packed 的结构仅仅

4、声明为__packed 的结构变量


五、后记
以上内容未经测试,由ADS编译器手册及相关资料理解总结所得。
不建议使用__packed 来节省数据大小,因为这需要付出减低执行效率和浪费代码空间的代价。
继承事业,薪火相传
返回列表