标题: __align的用法 [打印本页]

作者: liuyy    时间: 2015-1-12 01:45
标题: __align的用法
__align:
__align 关键字指示编译器在 n 字节边界上对齐变量。
__align 是一个存储类修饰符。 它不影响函数的类型。

语法:
__align(n)
其中:
n是对齐边界。
对于局部变量,n 可以具有值 1、2、4 或 8。
对于全局变量,n 可以具有最大为 2 的 0x80000000 次幂的任何值。
__align 关键字紧靠变量名称前面放置。

用法:
如果声明的变量的常规对齐边界小于 n,__align(n) 是非常有用的。 八字节对齐方式可以显著提高 VFP 指令的性能。
可以将 __align 与 extern 和 static 一起使用。

限制:
由于 __align 是存储类修饰符,因此不能将其用于:类型,包括 typedef 和结构定义函数参数。
只能进行过对齐。 也就是说,可以将两个字节的对象按 4 个字节对齐,而不能将 4 个字节的对象按两个字节对齐。

相关知识点扩展:

1.使用指针对未对齐地址数据访问

        当使用*int指针进行数据访问时,ARM的编译器会使用LDR指令读取数据,LDR指令要求被访问的地址是四字节对齐的,如果指针地址是四字节非对齐的,那么会访问地址卷绕后的地址上的数据。这个卷绕就是说的两条存取指令对地址的圆整。
        如果想使用*int存取任何地址上的数据,那么可以使用_packed描述符来说明。这样定义以后,ARM编译器将不在使用LDR指令,而是使用其他方法进行数据的存取,最后凑成一个正确的数据,这样会浪费很多指令周期。
        但是有些情况还必须使用这种单字节对齐的方式进行数据的存取,典型的例子就是设备之间的数据传输。再有一个需要注意的就是两个设备是不是具有相同的端模式。


2.结构体成员的对齐

        为了数据地址的对齐,编译器会在结构体内插入一些padding.如果不想让编译器插入 padding,可以如下定义:
_packed struct mystruct{  };
        这样结构体内的数据会在内存中依次存放。


3.使用编译选项--min_array_alignment=option,该编译选项规定数组的最小对齐字节数。

例:
        使用该 --min_array_alignment=8编译下面的程序,对齐字节数分别如下:
char arr_cl[1];                       //alignment==8
char cl;                                  //alignment==1
char arr_c2[3];                      //alignment==8
char arr_c3[10];                                        //alignment==8                    
        因为编译器选项会影响使用该编译器选项的所有文件,而并不是所有的数据都要求这么存放的,所以不要在整个工程中增加此类编译选项,最好是控制在一定的范围内使用。对于嵌入式系统规划人员,可以考虑如何布局此类编译选项,预防此类问题的发生,认真规划此类问题可以让不同水平的人员都避免低级错误的发生。






欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1