有点掩蔽问题的好方法是什么?

时间:2017-12-18 21:49:24

标签: c embedded bit-manipulation bitmask

问题

  • 我想在不影响其他位的情况下将位组合更改为其他组合。
  • 在此合并中,某些位必须取消设置设置

问题:什么是最好的屏蔽解决方案。特别是对于未设置 masking.I

一个例子:改变位[3:0] - > 0b1011(数据)             目的位[3:0] - > 0b0110

让我分享一下我的尝试:

  • 创建一个未设置的掩码:1的补充0b1001 - > [1111] 0110(将不关心位改为1)
  • 创建了面具:0b0110

使用这两个掩码,我可以使用按位操作。

int data = 0xB;         /*0b1011 (0xb) -> 0110 (0x6)*/
int umask = 0x9;        /*unset mask 0b1001*/
int smask = 0x6;       /*Set Mask 0b0110*/

data &= ~umask;        /*Unset the bits what needs without affecting other*/
data |= smask;         /*Set the bits what needs to be set*/

1 个答案:

答案 0 :(得分:2)

简单的答案是肯定的,你使用1个掩码来清除要清除的位,而另一个用于设置你想要设置的位。但是,有时候,您需要注意隐藏的硬件级别,具体取决于掩码和数据的使用方式以及它们的用途。

如果您只想将4位设置为值:

val &= ~(0xf); // This only clears the low 4 bits, preserving the rest.

assert((new4BitMaskvalue & ~0xf) == 0); // Make sure new mask only plays with low 4 bits.
val |= new4BitMaskvalue;  // or new mask

您在技术上清除了一些额外的位,但这允许您在清除时仅使用一个通用掩码。你也可以像你一样清除确切的位,但这可能没有必要。

如果您在CPU支持的内存单元大小中一次设置所有字段,通常可以分配整个值并保存一个步骤。 (U8 / U16 / U32 / U64 /等)

现在,"有趣"部分。如果这些位代表实际的硬件寄存器,您可能无法设置这样的整个字段,因为它可能会导致令人兴奋的行为。也许这是一个中断使能寄存器。如果是这样,清除和重置不需要清除和设置的位将导致意外的副作用。此外,寄存器通常只能读取或写入,您需要再次注意屏蔽方式,甚至可能被迫一次设置或清除单个位。

简而言之,是的,您通常需要至少2个值来清除和设置位。通常可以允许第一个not and面具清除您关心的所有位,这样您就不需要2个特殊面具。