ARM编译器中对齐的使用__align和__packed

来源:互联网 发布:陈默外推软件包月 编辑:程序博客网 时间:2024/05/22 15:26

以下是我整理的__align和__packed的使用,希望对大家有用

1.__align(num)  

 

__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 个字节的对象按两个字节对齐。

__align(8) char buf[128];  // buffer starts on eight-byte boundaryvoid foo(void){    ...    __align(16) int i; // this alignment value is not permitted for                       // a local variable    ...}
__align(16) int i; // permitted as a global variable.

这个用于修改最高级别对象的字节边界。在汇编中使用LDRD或者STRD  
   
就要用到此命令__align(8)进行修饰限制,来保证数据对象是相应对齐。  
   
这个修饰对象的命令最大是8个字节限制,可以让2字节的对象进行4字节  
   
对齐,但是不能让4字节的对象2字节对齐。  
   __align
是存储类修改,他只修饰最高级类型对象,不能用于结构或者函数对象  

  比如:__align(4) u8 mem1base[MEM1_MAX_SIZE];//保证分配的数组空间4字节对齐,同时保证数组首地址可被4整除


2.__packed的使用

__packed字节对齐的意思。
比如说intfloat double char它的总大小是4 + 4 + 8 + 1 = 17
但如果不用__packed的话,系统将以默认的方式对齐(假设是4字节),那么它占4+ 4 + 8 + 4 = 20;(不足4字节以4字节补齐)。


下面两个结构体的区别是什么?

typedef __packed struct READ_Command
{
    u_char code;
    u_int addr;
    u_char len;
} READ_Command;

typedef  struct READ_Command
{
    u_char code;
    u_int addr;
    u_char len;
} READ_Command;

回答:没有__packed的会出现字对齐等也就是,char型的有可能是占用4个字节的长度的内存空间有__packed 的就不会,就肯定是1个字节的内存空间,是gcc编译器的关键字。(不止vc下面32位的系统里面的内存数据的存取是32位的,处理的时候都是4个字节为单位,通常也就是int的长度。如果不定义压缩方式,也就是编译选项没有诸如#pragma pack(1)之类的,那么系统会进行4字节对齐)

注意:_packed只是某种编译器的格式压缩,有的是pack呢,对不同的CPU压缩的对齐方式也不一样,在使用了该关键以后在进行操作时需要格外小心。

声明结构类型时,可以包含一个保留字packed,用于实现压缩数据存储。

      当一个记录类型在   {$A-}   状态下声明或者声明中包括了保留字   packed   时,记录中的字段不被调整,而替换为赋予连续的偏移量。这样一个压缩记录的总尺寸就是所有字段的尺寸的和。因为数据调整尺寸可能改变(如不同版本的编译器对同一种数据类型的调整值可能不同),所以当想要把记录写入磁盘时或者在内存中传递到另一模块而该模块由不同版本的编译器编译时,最好还是压缩所有的记录。

 

 


对齐的使用:
1.__align(num)
   这个用于修改最高级别对象的字节边界。在汇编中使用LDRD或者STRD

   就要用到此命令__align(8)进行修饰限制。来保证数据对象是相应对齐。

   这个修饰对象的命令最大是8个字节限制,可以让2字节的对象进行4字节

   对齐,但是不能让4字节的对象2字节对齐。

   __align是存储类修改,他只修饰最高级类型对象不能用于结构或者函数对象。

   
2.__packed 
__packed是进行一字节对齐

1.不能对packed的对象进行对齐

2.所有对象的读写访问都进行非对齐访问

3.float及包含float的结构联合及未用__packed的对象将不能字节对齐

4.__packed对局部整形变量无影响

5.强制由unpacked对象向packed对象转化是未定义,整形指针可以合法定

义为packed
     __packed int* p;//__packed int 则没有意义



相关更多stm32字节对齐问题的讨论,请参考正点原子相关帖子http://www.openedv.com/thread-7415-1-1.html