ARMCC:memcpy问题(对齐异常)

时间:2014-07-22 09:18:09

标签: c memcpy memory-alignment armcc

我正在将一些软件从gcc-toolchain移植到armcc-toolchain(处理器保持不变(Cortex-A9))。在C代码中使用memcpy。 armcc通过调用__aeabi_memcpy替换对memcpy的调用。常见问题解答如下关于__aeabi_memcpy(How do the ARM Compilers handle memcpy()?):

  

在许多情况下,当编译对memcpy()的调用时,ARM C编译器将生成对专用的,优化的库函数的调用。自RVCT 2.1以来,这些专用函数是ARM体系结构(AEABI)的ABI的一部分,包括:

__aeabi_memcpy
This function is the same as ANSI C memcpy, except that the return value is void.

但是与gcc相反,在我的所有情况下,对memcpy的调用都可以正常工作,使用armcc对memcpy的调用__aeabi_memcpy会连续产生对齐异常。同时我发现,对memcpy的调用可以处理源和目标地址不是4字节对齐的调用,但前提是它们都不是4字节对齐的。例如:

    volatile uint32_t len = 10;
    uint8_t* src = (uint8_t*)0x06000002;         // 2-byte aligned
    uint8_t* dst = (uint8_t*)(0x06000002 + 20);  // 2-byte aligned
    memcpy(dst, src, len);

会奏效。但是例如:

    volatile uint32_t len = 10;
    uint8_t* src = (uint8_t*)0x06000002;         // 2-byte aligned
    uint8_t* dst = (uint8_t*)(0x06000002 + 22);  // 4-byte aligned
    memcpy(dst, src, len);

会导致对齐异常。我正在使用uint8_t类型的指针*我明确告诉编译器地址可以有任何对齐。但显然这个__aeabi_memcpy无法处理每个路线组合。如何解决此问题(最好不使用用户特定版本的memcpy更改现有代码中对memcpy的所有调用)?感谢帮助。

2 个答案:

答案 0 :(得分:0)

如果您不想更改代码,可以选择以下两个选项:

1)禁用Cortex-A9上的未对齐异常。这完全解决了问题,但您可能会受到性能影响。

2)修补图书馆。您可以在要链接的lib文件中重命名符号__aeabi_memcpy。然后,您可以实现自己的__aeabi_memcpy来检测对齐错误,使用专门的例程处理它或跳转到原始的memcpy函数。如果您使用的是Linux,则甚至不需要重命名该符号。链接器允许您覆盖函数。

这两种解决方案都很脏,但是如果你不想改变代码,这就是我能想到的全部。

哦,你应该提交错误报告。你见过的行为肯定是一个错误。任何对齐都可以使用Memcpy。

答案 1 :(得分:0)

也许这仍然有帮助: ARM编译器armcc应该有一个选项,您可以使用该选项告诉编译器不要进行未对齐访问,也不要使用内置库来执行此操作:

--no_unaligned_access

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472k/chr1359124947629.html