iOS模拟器内存对齐

4

我正在测试对齐并发现iOS模拟器有些奇怪的东西。(XCode 4.3.2和XCode 4.5)

在iOS模拟器中,即使使用属性((aligned(4)))强制为4字节边界,结构体仍会被对齐到8字节边界。检查是否末尾填充了0x00000001来对齐到8字节边界。

如果myStruct变量在全局作用域中定义,则模拟器将其对齐到4字节边界,因此可能与堆栈相关。

模拟器是i386,因此它是32位的,必须对齐到4字节边界。那么,它对齐到64位边界的原因是什么?这是一个功能还是一个错误?

(我知道与模拟器斗争并不必要,但它可能导致陷入微妙的问题。)

typedef struct myStruct
{
    int a;
    int b;
} myStruct;
//} __attribute__ ((aligned (4))) myStruct;

-(void)alignmentTest
{
    // Offset 16*n    (0x2fdfe2f0)
    int __attribute__ ((aligned (16))) force16ByteBoundary = 0x01020304; 

    // Offset 16*n-4  (0x2fdfe2ec)
    int some4Byte = 0x09080706;

    // Offset 16*n-12 (0x2fdfe2e4)
    myStruct  mys;

    mys.a = 0xa1b1c1d1;
    mys.b = 0xf2e28292;

    NSLog(@"&force16ByteBoundary: %p / &some4Byte: %p / &mys: %p",
       &force16ByteBoundary, &some4Byte, &mys);
}

(编辑 优化关闭,-O0)

  • 模拟器(iOS 5.1) 测试结果;

    (lldb) x `&mys` -fx

    0xbfffda60: 0xa1b1c1d1 0xf2e28292 0x00000001 0x09080706

    0xbfffda70: 0x01020304

    &force16ByteBoundary: 0xbfffda70 / &some4Byte: 0xbfffda6c / &mys: 0xbfffda60

  • 设备(iOS 5.1) 测试结果;

    (lldb) x `&mys` -fx

    0x2fdfe2e4: 0xa1b1c1d1 0xf2e28292 0x09080706 0x01020304

    &force16ByteBoundary: 0x2fdfe2f0 / &some4Byte: 0x2fdfe2ec / &mys: 0x2fdfe2e4

(新发现)

- On Simulator and Device;
    - Building for Release or Debug does not make any difference for alignments.
    - Local or global variables of "long long", double types are aligned to 8 byte boundary although they must be aligned to 4 byte boundary. 
    - There is no problem with global variables of structs.
- On Simulator;
    - Local variables of structs are aligned to 8 byte boundary even when there is only a char member in the struct.

(编辑)

我只能在这里找到iOS的“数据类型和数据对齐方式” (链接)。 另外,它们可以从ILP32对齐方法中推断出来。


2
模拟器是英特尔,iDevice 是 ARM……不同的架构……ARM 在字节对齐方面更加严格,而英特尔则更加宽容。 - Tim Reddy
您运行模拟器的设备是64位的吗? - Guilherme Torres Castro
在调试版本和发布版本中,结果是否相同? - rob mayoff
我已经考虑了Mac OS X的位数,也许这就是真正的原因。只需要官方确认它的要求(如果OS X和模拟器的内存之间存在直接映射,则需要)。我将尝试调试和发布版本。 - lockedscope
1个回答

0

通常,对齐属性只影响结构体内部项目的相对对齐方式。这使得与从网络或二进制文件直接复制数据到结构体的代码向后兼容。

对齐属性不会影响在堆栈上分配的局部变量的对齐方式。堆栈上项目的排序和对齐不被保证,并且通常会为设备的每个项目进行最佳对齐。因此,如果基于386的设备可以通过8字节对齐从内存中获取64位长整型数据,则会执行此操作。有些处理器实际上会因数据未完全对齐而失去大量性能。有些处理器可能会因尝试读取未正确对齐的数据而引发异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接