这是csdn里面的一个讨论: linux
http://bbs.csdn.net/topics/300096265 数据结构
在ARM core的平台(StrongARM, 2410, XScale)上,若是企图经过一个独立的指针对某个数
据结构的内部成员域进行定位和访问时,会遇到下面的问题(注,在IA-32 X86平台不会出现
这样的问题)。
定义一个数据结构:
struct __attribute__((packed)) test {
char c; // 1个字节
short s; // 2个字节
long l; // 4个字节
} st;
packed属性,对应于gcc编译选项 -fpack-struct;
test的内存布局在该属性的制约下是紧凑的,也就意味着第二、3个成员s、l的起始地址将是
奇地址。
若是另行定义一个独立指针: unsigned long t;
经过“t+偏移字节数”的方式来定位(访问)结构内成员域,则会在强制类型转换t指针来赋值
或者读取相应成员域时,出现下面的问题:
(假定该结构的起始地址为A0, 则c、s、l的地址各为A0、A一、A3)
1. 编译器版本(arm version):GCC 2.95.2 / 3.2 / 3.3.2
t = (unsigned long) &st;
*((short*)(t+1)) = 0x0201;
指望: 0x01赋于A1字节, 0x02赋于A2字节
实际: 0x01赋于A0字节, 0x02赋于A1字节,与指望不吻合
*((long*)(t+3)) = 0x08070605;
指望: 0x05 - 0x08 逐次赋于 A3 - A6 字节
实际: 0x05 - 0x08 逐次赋于 A0 - A3 字节,与指望不吻合
结论: 基于这些GCC版本,若是对奇地址进行强制类型转换,企图得到"字、双字"的数据类型,
则强制转换后所得到的数据类型,其地址将被自动"优化"为最近的可被相应对齐模数
(字型数据的对齐模数是2,双字的是4)整除的低位偶地址!
2. 编译器版本(arm version):GCC 2.95.3 / 3.0
t = (unsigned long) &st;
*((short*)(t+1)) = 0x0201;
指望: 0x01赋于A1字节, 0x02赋于A2字节
实际: 0x01赋于A1字节, 0x02赋于A2字节,与指望吻合
*((long*)(t+3)) = 0x08070605;
指望: 0x05 - 0x08 逐次赋于 A3 - A6 字节
实际: 0x05 - 0x08 逐次赋于 A0 - A3 字节,与指望不吻合
结论: 基于这些GCC版本,若是对奇地址进行强制类型转换,企图得到"双字"的数据类型,
则强制转换后所得到的数据类型,其地址将被自动"优化"为最近的可被相应对齐模数
4整除的低位偶地址!但对字型数据的此类操做,却不会引发这种指针优化。
附,有资料称:
某些架构上访问数据时有对齐的要求,好比只能从4字节边界上读取一个4字节的数据类型。
IA-32架构没有硬性要求对齐,尽管未对齐的访问下降执行效率。另一些架构,好比MIPS、
SPARC、m68k、ARM(<V3),要求对齐访问,不然向当前进程分发SIGBUS信号,主要是相对早
期的RISC CPU存在此问题。
那么有没有一个办法(好比gcc的编译选项,或者一个__attribute__),能制约上述的这种指针优化,
使其不自动发生!从而使实际操做与指望操做相吻合?
进一步地问,为什么不一样版本的arm-linux-gcc所编译出的执行码的在这个问题上的表现不同!?
这后面有更深层的理论背景吗?
================
若是endian是肯定的,我喜欢这样的形式:((unsigned char*)&s)[0] * 256 + ((unsigned char*)&s)[1]
=============================
en,这样把操做分解成基于字节的处理确实是一个变通的办法,和本人的考虑是一致的;在找不出更好解决方法的状况下,我认为能够有下面3种办法来回避这样的问题:
1. 改变数据源的结构布局,放弃紧凑布局;
代价:增长并浪费了 padding 字节,且既有应用须要重写,以配合结构体内存布局的变化;
2. 改变对结构成员的访问方式,放弃经过独立指针来定位/读写成员域,而直接采用成员名的方式访问;
代价:既有应用程序的改动范围较大;
3. 维持目前的数据源和数据访问方式,而新增一个过渡层,表现形式能够是一组宏,或者内联函数,或
者函数,对结构体内的一切字或双字型数据的访问,经过这个过渡逻辑被分拆为以字节为基础的操做,
从而回避指针强制类型转换时发生优化;这也一样是nxin的思路!
代价:既有应用程序在访问结构体成员时的代码形式发生变化,但我的认为这种方法对系统总体代码的
影响是最小的。 架构