【问题标题】:C Bit masking registersC 位屏蔽寄存器
【发布时间】:2015-07-09 15:47:27
【问题描述】:

我已经有一段时间没有用 C 编程并做过任何位掩码了。

我的问题是,在我的设备启动过程中,我的设备驱动程序正在初始化寄存器中的位,但假设其中只有一些是可变的。我知道哪些位是可变的,并且我知道它们应该是什么取决于内存位置。

例如: $0x00AA 应该始终具有格式 0b101XXX01,其中 X 是可变的,其他一切都应该保持不变。 该函数当前接收一个地址和一个值,并将该值设置为该地址。我需要修改它,这样即使函数在 0b11111111 中传递给寄存器 $0x00AA,它也应该设置为 0b10111101。 同样,对于 0b00000000 到 0b10100001。

【问题讨论】:

  • 您可以为此使用按位运算符(|&~),尤其是赋值运算符版本(|=&=)。
  • 你的意思是你想要一个按位与?
  • 您需要检测传入的地址是您的受保护地址之一,在这种情况下,在设置之前对值应用掩码。您有多少个受保护的地址,它们是否在其他地方使用?

标签: c bitmask


【解决方案1】:

您可以先用按位与屏蔽除可变位之外的任何内容,然后用按位或添加常量位。

void set_register(uint8_t value) {
    const uint8_t MUTABLE_BITS = 0x1C;  // 0b00011100 <- only mutable bits
    const uint8_t CONSTANT_BITS = 0xA1; // 0b10100001 <- constant 1-bits

    value &= MUTABLE_BITS; // remove any non-mutable bits
    value |= CONSTANT_BITS; // add the constant bits
    my_register = value;
}

这种方法具有对常量位的值进行硬编码的可疑特性(根据名称“常量”)。另一种方法是仅设置可变位并从寄存器本身获取其余值(按位与可变位掩码的补码),例如:

void set_register(uint8_t value) {
    const uint8_t MUTABLE_BITS = 0x1C;  // 0b00011100 <- only mutable bits

    value &= MUTABLE_BITS; // remove any non-mutable bits
    value |= my_register & ~MUTABLE_BITS; // take other bits from register
    my_register = value;
}

(至于对具有不同掩码的多个寄存器执行此操作的要求,我希望它们的数量足够有限,您可以一个一个地设置它们。如果您真的需要一个接收指针和一个值,然后您必须根据已知的受保护地址检查该指针并以某种方式获取适当的掩码。该范围的选择从 if/elseswitch 到二进制搜索到某种哈希映射。)

【讨论】:

    猜你喜欢
    • 2021-10-27
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    相关资源
    最近更新 更多