当前位置: 代码迷 >> 驱动开发 >> ARM指令字对齐有关问题-只要考虑结构体内的变量对齐有关问题嘛
  详细解决方案

ARM指令字对齐有关问题-只要考虑结构体内的变量对齐有关问题嘛

热度:5337   发布时间:2013-02-26 00:00:00.0
ARM指令字对齐问题-只要考虑结构体内的变量对齐问题嘛?
一。问题的背景:
--在结构中,编译器为结构的每个成员按其自然对界条件分配空间;各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。在缺省情况下,c编译器为每一个变量或是数据单元按其自然对界条件分配空间。

--更改c编译器的缺省分配策略 
  一般地,可以通过下面的两种方法改变缺省的对界条件: 
  ? 使用伪指令#pragma pack ([n]) 
  ? 在编译时使用命令行参数 
          #pragma pack ([n])伪指令允许你选择编译器为数据分配空间所采取的对界策略;
 例如,在使用了#pragma pack (1)伪指令后,test结构各成员的空间分配情况就是按照一个字节对齐.

二。ARM平台的对齐问题
    在ARM中,有ARM和Thumb两种指令。
    ARM指令:每执行一条指令,PC的值加4个字节(32bits).一次访问4字节内容,该字节的起始地址必须是4字节对齐的位置上,即地址的低两位为bits[0b00],也就是说地址必须是4的倍数。
    Thumb指令:每执行一条指令,PC的值加2个字节(16bits).).一次访问2字节内容,该字节的起始地址必须是2字节对齐的位置上,即地址的低两位为bits[0b0],也就是说地址必须是2的倍数。
     遵循以上方式叫对齐(aligned)方式,不遵守这样方式称为非对齐(unaligned)的存储访问操作。
三、ARM平台字节对齐关键字
  1. __align(num)用于修改最高级别对象的字节边界。
    A、在汇编中使用LDRD或者STRD时,就用到此命令__align(8)进行修饰限制。来保证数据对象是相应对齐。
    B、该修饰对象的命令最大是8个字节限制,可让2字节的对象按4字节对齐,但不能让4字节的对象2字节对齐。
    C、 __align是存储类修改,他只修饰最高级类型对象不能用于结构或者函数对象。   
  2. __packed 是进行一字节对齐。
    A、不能对packed的对象进行对齐;
    B、所有对象的读写访问都进行非对齐访问;
    C、float及包含float的结构联合及未用__packed的对象将不能字节对齐;
    D、__packed对局部整形变量无影响;
    E、强制由unpacked对象向packed对象转化是未定义,整形指针可以合法定义为:
       packed __packed int* p; //__packed int 则没有意义。
  3. __unaligned   用于修饰该变量可按照非对齐访问。
四、如何查找与字节对齐方面的问题,如果出现对齐或者赋值问题首先查看:
  1. 编译器的big little端设置;
  2. 看这种体系本身是否支持非对齐访问;
  3. 如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作。
五、结论
   针对于32位处理器对于本地使用的数据结构,为提高内存访问效率,采用四字节对齐方式;同时为了减少内存的开销,合理安排结构成员的位置,减少四字节对齐导致的成员之间的空隙,降低内存开销。

--这里不理解,意思是只要考虑结构体内的变量对齐问题嘛?
编译器 ARM 字对齐

------解决方案--------------------------------------------------------
一般来讲,只要不涉及到强制指针类型转换,就不用考虑对齐问题。
------解决方案--------------------------------------------------------
不同意一楼,强制类型转换有可能产生mis-align的异常,必须是考虑的
但是在结构体内,也是要考虑的,否则可能因为对齐造成取数据错误。结构体的全局变量还罢了,指向结构体的指针怎么保证?还是会产生异常。
如果无法保证指针,还是用packed比较保险,代价是效率降低。对于现在的CPU处理速率,这点效率的影响微乎其微。
------解决方案--------------------------------------------------------
引用:
一般来讲,只要不涉及到强制指针类型转换,就不用考虑对齐问题。

真被你说中了,我就中过这么个招。
  相关解决方案