【问题标题】:C memory address - what is wrong with the code?C 内存地址 - 代码有什么问题?
【发布时间】:2017-04-16 21:05:01
【问题描述】:

最近有人问我,看看下面的代码有什么问题,我应该如何修复它:

// Memory-mapped peripheral
#define STATUS_REG_ADDR 0x12345678 // 32-bit status register
#define DATA_REG_ADDR   0x1234567C // 32-bit data register

// Status register bits
#define BUSY_BIT_MASK 0x00000080   // Busy bit == '1' while peripheral busy

uint32_t get_value()
{ 
    while (((*(uint32_t*)STATUS_REG_ADDR) & BUSY_BIT_MASK) == 1)
        ;

    return *(uint32_t*)DATA_REG_ADDR;
}

我以前从未做过类似的事情,所以我尝试在 IDE 中运行它,我看到 return 语句给出了分段错误,但我不知道如何解释它以及是否还有更多错误。

【问题讨论】:

  • 您确定可以在运行它的任何计算机上读取该地址吗? (由于某些特定于体系结构的原因,它是一个硬编码地址吗?)另外,如果该位被设置,x & 0x80 不会是0x80,如果它被清除则为零? (永远不等于1
  • 所以这更像是我几天前遇到的一个挑战,我无法回答。我真的不知道如何回答它。所以,我问的是,这样的代码一般有什么问题,为什么?
  • 此外,我不明白为什么 return 语句给出了分段错误。是不是因为找不到内存地址?还是?
  • 您可能需要将 STATUS 地址转换为 (volatile uint32_t *) 以通知编译器内存值可能会独立于正在编译的指令发生变化。

标签: c debugging pointers memory memory-address


【解决方案1】:

问题在于while 循环条件。

您的BUSY_BIT_MASK 是 0x00000080。任何与 0x80 的 AND 都不会等于 1,因为它的 LSB 为 0。任何与 0 的 AND 总是 0。

你必须修改条件为

while (((*(uint32_t*)STATUS_REG_ADDR) & BUSY_BIT_MASK) == BUSY_BIT_MASK)

因此,当设置标志时,它将与 0x80 进行“与”运算,输出将为 0x80。 (1 AND 1 = 1)

您收到 SegFault 是因为您考虑的地址在您的计算机上无效。您必须使用有效地址。您正在尝试访问可能不存在的随机内存或内存地址 - 这就是 SegFault 的原因。

【讨论】:

  • 非常感谢您的回答。我现在明白发生了什么。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 2016-11-15
  • 2011-10-10
  • 2017-05-02
相关资源
最近更新 更多