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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有点掩蔽问题的好方法是什么?相关的知识,希望对你有一定的参考价值。

问题

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

问题:什么是最好的掩蔽解决方案。特别是对于未设置的掩蔽.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个掩码清除要清除的位,另一个用于设置你想要设置的位。但是,偶尔会有隐藏的硬件级别需要注意的事项,具体取决于掩码和数据的使用方式以及它们的用途。

如果您只想将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个特殊掩码。

以上是关于有点掩蔽问题的好方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章

将初始数据提供给片段的正确方法?

什么是掩蔽效应?

什么是掩蔽效应?

C# 最有用的(自定义)代码片段是啥? [关闭]

有没有人知道格式化“缩写”数字的好 javascript 片段?

用 SnapKit 构建堆叠视图的好方法是啥