简体   繁体   English

使用 C 在 ARM9 上未对齐的 memory 访问异常的解决方法是什么?

[英]What is the workaround for unaligned memory access exception on ARM9 using C?

Architecture ARM9.架构 ARM9。 Programming Language C.编程语言 C。

We have a third-party stack and one of the calls takes a pointer( pBuffer ) to a memory location.我们有一个第三方堆栈,其中一个调用需要一个指向 memory 位置的指针 ( pBuffer )。 Within the stack, they are free to move around the pointer passed and access it as they wish.在堆栈中,它们可以自由地在传递的指针周围移动并根据需要访问它。 Unfortunately, they offset the passed in pointer and passed it into a another function that tried to do this from an odd/unalighed memory location不幸的是,他们偏移了传入的指针并将其传递到另一个 function 试图从奇数/未对齐的 memory 位置执行此操作

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

where value is of type uint16 and index is bounds checked and indexes pBuffer .其中valueuint16类型, index是边界检查和索引pBuffer This causes a unaligned memory access exception.这会导致未对齐的 memory 访问异常。 pBuffer points to char * on the heap. pBuffer指向堆上的char *

As mentioned, even though we can peek into the third-party stack, we can not update the code officially.如前所述,即使我们可以窥视第三方堆栈,我们也不能正式更新代码。 So we notify the provider and they provide the update in the next release.所以我们通知提供商,他们会在下一个版本中提供更新。

I want to understand if there is a work around for this.我想了解是否有解决此问题的方法。 How do I perform the above assignment without violating the unaligned access?如何在不违反未对齐访问的情况下执行上述任务? What is the best approach to resolving such problems.解决此类问题的最佳方法是什么。

Copy the value byte by byte.逐字节复制值。 Cast it to a (unsigned) char pointer, and then copy a byte at a time.将其转换为(无符号)char 指针,然后一次复制一个字节。

It's not pretty, but it doesn't sound like you have many options.它不漂亮,但听起来你没有很多选择。

If you are in control of pBuffer, as a work around, you could declare it as an array of uint32_t (or whatever matches the alignment of your architecture).如果您控制 pBuffer,作为一种变通方法,您可以将其声明为 uint32_t 数组(或任何与您的体系结构的 alignment 匹配的数组)。 With declaring the buffer as uint32_t, the compiler will choose the correct alignment.通过将缓冲区声明为 uint32_t,编译器将选择正确的 alignment。 You can cast it to uint8_t* when calling your target function.您可以在调用目标 function 时将其转换为 uint8_t*。

This should work with the example code you posted, but may still fail if the third party code applies any unaligned offset to the buffer.这应该适用于您发布的示例代码,但如果第三方代码将任何未对齐的偏移量应用于缓冲区,仍可能会失败。

There are three possibilities, and I cannot determine from your question so far which is the case.有三种可能性,目前我无法从你的问题中确定是哪种情况。

Case 1: The index is always odd.情况 1:索引总是奇数。 Solution: memmove() pBuffer over 1 bytes Case 2: The index is sometimes odd, and you can predict up front when it will be.解决方案:memmove() pBuffer over 1 bytes 情况2:索引有时是奇数,您可以预先预测它何时会是奇数。 Solution: memmove() pBuffer over 1 byte when you know index will be odd.解决方案:当你知道索引是奇数时,memmove() pBuffer 超过 1 个字节。 Case 3: The index is sometimes odd, and you cannot predict when it will be.案例 3:索引有时是奇数,您无法预测何时会是奇数。 This is unfortunate, because the code will fault.这是不幸的,因为代码出错。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM