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

zhujinqiang 2013-01-22 11:23:01
一。问题的背景:
--在结构中,编译器为结构的每个成员按其自然对界条件分配空间;各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。在缺省情况下,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位处理器对于本地使用的数据结构,为提高内存访问效率,采用四字节对齐方式;同时为了减少内存的开销,合理安排结构成员的位置,减少四字节对齐导致的成员之间的空隙,降低内存开销。

--这里不理解,意思是只要考虑结构体内的变量对齐问题嘛?
...全文
355 4 点赞 打赏 收藏 举报
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
lr2131 2013-01-27
引用 1 楼 curious_cat 的回复:
一般来讲,只要不涉及到强制指针类型转换,就不用考虑对齐问题。
真被你说中了,我就中过这么个招。
  • 打赏
  • 举报
回复
zhujinqiang 2013-01-24
还是不很明白。。
  • 打赏
  • 举报
回复
daviddb7 2013-01-22
不同意一楼,强制类型转换有可能产生mis-align的异常,必须是考虑的 但是在结构体内,也是要考虑的,否则可能因为对齐造成取数据错误。结构体的全局变量还罢了,指向结构体的指针怎么保证?还是会产生异常。 如果无法保证指针,还是用packed比较保险,代价是效率降低。对于现在的CPU处理速率,这点效率的影响微乎其微。
  • 打赏
  • 举报
回复
curious_cat 2013-01-22
一般来讲,只要不涉及到强制指针类型转换,就不用考虑对齐问题。
  • 打赏
  • 举报
回复
相关推荐
发帖
驱动开发/核心开发
加入

2.1w+

社区成员

硬件/嵌入开发 驱动开发/核心开发
申请成为版主
帖子事件
创建了帖子
2013-01-22 11:23
社区公告
暂无公告