首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C结构,其中元素跨越字节边界并放置在下一个字节中

C结构,其中元素跨越字节边界并放置在下一个字节中
EN

Stack Overflow用户
提问于 2018-11-30 10:21:48
回答 2查看 92关注 0票数 0

我有下面的C结构,表示外部芯片中的一个寄存器

代码语言:javascript
复制
typedef union {
    // Individual Fields
    struct {
        uint8_t ELEM_1 : 4 ; // Bits 0-3
        uint8_t ELEM_2 : 3 ; // Bits 4-6
        uint8_t ELEM_3 : 2 ; // Bits 7-8
    } field;
    // Complete Value
    uint32_t value;
} ELEMENTS_t;

正如您所看到的,ELEM_1和ELEM_2可以毫无问题地放入一个字节中,并且在访问时,汇编代码如下所示

代码语言:javascript
复制
    ELEMENTS.field.ELEM_2 = 0x7;
  101488:   e55b3028    ldrb    r3, [fp, #-40]  ; 0xffffffd8
  10148c:   e3833070    orr r3, r3, #112    ; 0x70
  101490:   e54b3028    strb    r3, [fp, #-40]  ; 0xffffffd8
    ELEMENTS.field.ELEM_1 = 0xf;
  101494:   e55b3028    ldrb    r3, [fp, #-40]  ; 0xffffffd8
  101498:   e383300f    orr r3, r3, #15
  10149c:   e54b3028    strb    r3, [fp, #-40]  ; 0xffffffd8

它们都被写入具有正确位顺序的同一字节中。

问题是当我们到达ELEM_3时,该元素跨越了字节边界,因为它应该放在位8:7中,并且为了避免多次内存访问(可能),编译器将它放在一个完全独立的字节中,所以当我试图访问它时,它看起来像这样

代码语言:javascript
复制
    ELEMENTS.field.ELEM_3  = 0x3;
  10147c:   e55b3027    ldrb    r3, [fp, #-39]  ; 0xffffffd9
  101480:   e3833003    orr r3, r3, #3
  101484:   e54b3027    strb    r3, [fp, #-39]  ; 0xffffffd9

当逐个字段访问这些元素时,这不会导致问题,但当尝试将数据刷新到外部芯片时,它会导致问题。

有没有人知道如何告诉编译器把所有的代码打包在一起?它使用的是Xilinx SDK,目标是嵌入Zynq SoC中的ARM Cortex-A9处理器。

EN

回答 2

Stack Overflow用户

发布于 2018-11-30 10:28:56

你不能把9位压缩到一个字节中。所以它跨越了字节边界。如果寄存器为单字节,则应仅访问位0至7。

如果您需要同时设置多个位,可能还有其他问题。

票数 0
EN

Stack Overflow用户

发布于 2018-11-30 10:47:57

我找到了一个解决方案。如果我将所有元素设置为uint32_t而不是uint8_t,它将一次读写32位寄存器,这使得操作可以正常工作。

代码语言:javascript
复制
    ELEMENTS.field.ELEM_3 = 0x3;
  10147c:   e15b32b8    ldrh    r3, [fp, #-40]  ; 0xffffffd8
  101480:   e3833d06    orr r3, r3, #384    ; 0x180
  101484:   e14b32b8    strh    r3, [fp, #-40]  ; 0xffffffd8
    ELEMENTS.field.ELEM_2 = 0x7;
  101488:   e55b3028    ldrb    r3, [fp, #-40]  ; 0xffffffd8
  10148c:   e3833070    orr r3, r3, #112    ; 0x70
  101490:   e54b3028    strb    r3, [fp, #-40]  ; 0xffffffd8
    ELEMENTS.field.ELEM_1 = 0xf;
  101494:   e55b3028    ldrb    r3, [fp, #-40]  ; 0xffffffd8
  101498:   e383300f    orr r3, r3, #15
  10149c:   e54b3028    strb    r3, [fp, #-40]  ; 0xffffffd8
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53550330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档