在ARM9上使用C语言,如何解决未对齐内存访问异常?

5

架构 ARM9。编程语言 C。

我们有一个第三方堆栈,其中一个调用接受指向内存位置的指针(pBuffer)。在堆栈内部,他们可以自由移动传递的指针并按照他们的意愿访问它。不幸的是,他们偏移传入的指针并将其传递到另一个函数中,该函数试图从一个奇数/不对齐的内存位置进行操作。

         ((uint16 *)pBuffer)[index] = value;

其中value的类型为uint16index已进行边界检查并索引了pBuffer。这会导致未对齐内存访问异常。pBuffer指向堆上的char *

正如提到的那样,尽管我们可以窥视第三方堆栈,但我们不能正式更新代码。因此,我们通知供应商,并在下一个版本中提供更新。

我想了解是否有解决方法。如何执行上述任务而不违反未对齐访问?解决此类问题的最佳方法是什么。


除了对齐之外,如果使用gcc或类似的编译器,这也可能导致严格别名错误。像这样编写通用软件堆栈的人不知道他们在做什么...我希望你没有为此付钱。 - Lundin
谢谢 @Lundin。我们确实花了钱并从中获得了很多利润。Bugs是不可避免的,有时我们必须处理它们。他们最终在堆栈中修复了这个问题。再次感谢。 - dubnde
3个回答

7

逐字复制该值。将其强制转换为(无符号)char指针,然后逐个字节复制。

这不是很美观,但听起来似乎你没有太多选择。


1

有三种可能性,从你的问题中我无法确定是哪种情况。

情况1:索引始终为奇数。解决方案:使用memmove()将pBuffer向右移动1个字节。 情况2:索引有时为奇数,并且您可以预测何时会出现。解决方案:当您知道索引将为奇数时,使用memmove()将pBuffer向右移动1个字节。 情况3:索引有时为奇数,而您无法预测何时会出现。这很不幸,因为代码将会出错。


感谢MSalters。实际上这是第三种情况,所以在调用者方面无法做太多事情。执行此操作的实际例程已经提供给我们了。因此,他们将不得不进行更新,但我们可以非正式地进行更新,并指出问题所在,以便他们修复并提供更新的堆栈。 - dubnde

1
如果您控制pBuffer,可以将其声明为uint32_t数组(或与您的架构对齐匹配的其他类型)。通过将缓冲区声明为uint32_t,编译器将选择正确的对齐方式。在调用目标函数时,您可以将其转换为uint8_t*。
这应该适用于您发布的示例代码,但如果第三方代码对缓冲区应用任何不对齐的偏移量,则仍可能失败。

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