如何使用arm gcc为变量设置默认对齐方式

时间:2013-07-26 12:47:59

标签: gcc arm default memory-alignment

我正在开发一个arm7tdmi目标的应用程序。 我以前用IAR编译代码,但现在我切换到arm-none-eabi-gcc,我有以下问题。

typedef struct
{
    uint32 nNumber;
    uint32 nPara1;
    uint32 nPara2;
    uint32 nPara3;
    uint32 nPara4;
    uint32 nPara5;
    uint32 nParax[122];
} TTXSpecial_t;

static uint8 cTelBuf[TTX_TEL_LENGTH];

例如,cTelBuf放置在0x4000000A

&(((TTXSpecial_t *)cTelBuf)->nNumber)

返回相同的地址,到目前为止一切正常。

<小时/> cTelBuf已填满,((TTXSpecial_t *)cTelBuf)->nNumber应为0x87654321

内存转储显示:

0x40000000: 00 00 04 00 00 02 0C 00 00 02 21 43 65 87 00 00 
0x40000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<小时/> 问题是每当我阅读(TTXSpecial_t *)cTelBuf)->nNumber时,该值将为0x2004321。 因此,您可以看到读取是在地址0x40000008而非0x4000000A完成的。
我的cflags是:-mcpu=arm7tdmi -Os -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wpadded -Wstrict-prototypes -fstrict-aliasing -fverbose-asm -Wa
问题1:如何使用arm-none-eabi-gcc设置默认数据对齐
我知道在这种情况下static uint8 cTelBuf[TTX_TEL_LENGTH] __attribute__((aligned(4)));将解决问题,但我想设置一般的对齐方式。 IAR编译器是如何做到的?

问题2:有没有办法避免这个问题(没有复制)? 我的意思是:如果我希望TTXSpecial_t结构从cTelBuf+1开始,该怎么办? 一种解决方案可能是将cTelBuf+1 memcpy到已分配的TTXSpecial_t结构,但如何在不分配额外内存的情况下进行操作?

1 个答案:

答案 0 :(得分:3)

你的问题是你有类型而且不使用它们。编译器知道TTXSpecial_t包含需要4字节对齐的32位值。问题是您将cTelBuf声明为字节数组,其中编译器只能说字节访问不需要对齐。

所以我建议你将你的字节数组声明为你的实际类型TTXSpecial_t(并将其转换为对你的uint8的字节访问),或者通过将它声明为union来使其成为组合数据类型(即您重叠的TTXSpecial_tunit8数组。

Afaik gcc中没有通用选项可以更改变量的默认对齐方式(某些架构有特殊的-malign开关,但我手臂上的东西都不可用),快速浏览IAR文档说,IAR编译器的行为方式相同。这意味着他将你的结构类型的变量对齐为4字节边界,但声明的字节数组只能对齐1个字节 - 看起来你很幸运,你从来没有使用IAR编译器的代码问题 - 你应该修复它尽可能地发生在那里。