gpt4 book ai didi

c - 为什么会出现未对齐的内存访问错误? [皮质 M4]

转载 作者:行者123 更新时间:2023-12-04 10:48:26 32 4
gpt4 key购买 nike

我正在调试一段使用 Keil 编译器而不是 ARM-GCC 导致崩溃的代码。我不熟悉代码的历史,但是当我阅读更多内容时,我意识到代码中肯定至少存在严格的别名违规。然而,首先将我吸引到代码的错误是运行此代码段时未对齐的访问错误。

我很尴尬地承认我不是很清楚这种严格的别名违规的问题,并且想说服自己修复将解决问题,而不仅仅是掩盖导致未对齐错误的任何内容。

  • 有人能帮我理解为什么我看到未对齐的访问错误吗?这是否与严格别名违规有关,如果是,那是如何表现出来的?
  • 解决这个问题的最佳方法是什么?我已经将 sampleStruct 声明为 __packed 现在它似乎正在工作,但是对 sampleStruct 使用 union 会是更好的解决方案吗?或者更进一步,我需要复制结构的各个成员吗?

  • 我仍在学习更多关于严格混叠规则的知识,但如果能朝正确的方向推进,我将不胜感激。

    *注意:这是在 Cortex-M4 上的嵌入式系统中运行,永远不会在其他平台或硬件上运行。

    拆机:
        0x00031DF0 9802      LDR           r0,[sp,#0x08]
    64: structA->SessionCount = params.SessionCount;
    0x00031DF2 60A0 STR r0,[r4,#0x08]
    65: structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    0x00031DF4 9806 LDR r0,[sp,#0x18]
    65: structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    0x00031DF6 B140 CBZ r0,0x00031E0A
    65: structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    0x00031DF8 EDDD0A05 VLDR s1,[sp,#0x14]
    0x00031DFC ED9D0A06 VLDR s0,[sp,#0x18]
    0x00031E00 EEB81A40 VCVT.F32.U32 s2,s0
    0x00031E04 EE800A81 VDIV.F32 s0,s1,s2
    0x00031E08 E001 B 0x00031E0E
    65: structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    0x00031E0A ED9F0A1E VLDR s0,[pc,#0x78]
    > 0x00031E0E ED840A03 VSTR s0,[r4,#0x0C]
    66: structA->Value = params.ValueLast;
    0x00031E12 ED9D0A04 VLDR s0,[sp,#0x10]
    0x00031E16 ED840A04 VSTR s0,[r4,#0x10]
    67: structA->SessionValueLow = params.ValueLow;
    0x00031E1A ED9D0A07 VLDR s0,[sp,#0x1C]
    0x00031E1E ED840A05 VSTR s0,[r4,#0x14]
    68: structA->SessionValueHigh = params.ValueHigh;
    0x00031E22 ED9D0A08 VLDR s0,[sp,#0x20]



    58 case SESSION_INFO_HDL: {
    59 AppParams_t params;
    60 AppParamsRead(&params);
    61 sampleStruct_t *structA = (sampleStruct_t *) &pData->pValue[offset];
    62 structA->TotalCount = params.TotalCount;
    63 structA->SessionId = params.SessionId;
    64 structA->SessionCount = params.SessionCount;
    65 structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    66 structA->Value = params.ValueLast;
    67 structA->SessionValueLow = params.ValueLow;
    68 structA->SessionValueHigh = params.ValueHigh;
    69 structA->Reserved = 0;
    70 AttsSetAttr(SESSION_INFO_HDL, sizeof(*structA), &pData->pValue[offset]);
    71 break;
    72 }

    代码片段:https://godbolt.org/z/Djebj2
    typedef struct
    {
    uint8_t *pValue; /*!< \brief Pointer to the data's value */
    uint16_t *pLen; /*!< \brief Pointer to the length of the data's value */
    } data_t;

    typedef struct sampleStruct {
    uint32_t TotalCount;
    uint32_t SessionId;
    uint32_t SessionCount;
    float SessionValueAverage;
    float Value;
    float SessionValueLow;
    float SessionValueHigh;
    uint32_t Reserved;
    } sampleStruct_t;

    typedef struct AppParams {
    uint32_t TotalCount;
    uint32_t SessionId;
    uint32_t SessionCount;
    uint32_t CalibrationThreshold;
    float ValueLast;
    float ValueTotal;
    uint32_t ValueNum;
    float ValueLow;
    float ValueHigh;
    } AppParams_t;


    void function ( uint16_t offset, data_t * pData )
    {
    AppParams_t params;

    sampleStruct_t *structA = (sampleStruct_t *) &pData->pValue[offset];
    structA->TotalCount = params.TotalCount;
    structA->SessionId = params.SessionId;
    structA->SessionCount = params.SessionCount;
    structA->SessionValueAverage = params.ValueNum != 0 ? params.ValueTotal / params.ValueNum : 0.0f;
    structA->Value = params.ValueLast;
    structA->SessionValueLow = params.ValueLow;
    structA->SessionValueHigh = params.ValueHigh;
    structA->Reserved = 0;
    AttsSetAttr(SESSION_INFO_HDL, sizeof(*structA), &pData->pValue[offset]);

    send_data ( SESSION_INFO_HDL, &pData->pValue[offset], sizeof(*structA) );
    }

    最佳答案

    Cortex M4 支持以下指令的未对齐访问:

    •LDR、LDRT•LDRH、LDRHT•LDRSH、LDRSHT•STR、STRT•STRH、STRHT

    您发布的代码(甚至不会编译)使用不接受未对齐访问的指令的可能性很小。

    您的代码的修改版本(只是为了使其编译)https://godbolt.org/z/X_77Bc

    那么你为什么要得到 HF-s。

    两个可能的答案。

  • “配置和控制寄存器”中的 UNALIGN_TRP 位已设置。如果设置了任何未对齐的访问将触发异常(exception)
  • 您未显示的代码使用 LDM、STM、LDRD 或 STRD 指令,如果访问未对齐,则这些指令始终为 HF
  • 关于c - 为什么会出现未对齐的内存访问错误? [皮质 M4],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59592724/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com