C 内存地址 - 代码有什么问题?

C memory address - what is wrong with the code?

最近有人问我,看看下面的代码有什么问题,我该如何解决:

// 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 语句给出了分段错误,但我没有知道怎么解释,如果还有什么不对的。

问题出在 while 循环条件中。

你的 BUSY_BIT_MASK 是 0x00000080。任何与 0x80 相与的东西都不等于 1,因为它的 LSB 是 0。任何与 0 相与的东西总是 0。

您必须将条件修改为

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

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

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