标题:
ARM数据对齐 ----- ADS1.2编译
[打印本页]
作者:
yuyang911220
时间:
2014-7-26 09:05
标题:
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
,两个变量是连续分配的。
2
、
Usigned short
是
2
字节的,那么数据就按
2
字节对齐。
定义两个变量如下:
usigned char a08;
Usigned short a16;
如果
a08
所在的地址为
0x80000002
,那么
a16
所在的地址为
0x80000004
,
a16
不会分配到
0x80000003
,默认情况下,编译器为
usigned short
类型的变量分配到
2
的倍数的地址处。
2
、
usigned long
是
4
字节的,那么数据就按
4
字节对齐。
定义两个变量如下:
usigned char a08;
Usigned long a32
如果
a08
所在的地址为
0x80000005
,那么
a16
所在的地址为
0x80000008
,
a32
不会分配到
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
来节省数据大小,因为这需要付出减低执行效率和浪费代码空间的代价。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0