【问题标题】:How to set and clear different bits with a single line of code (C)如何使用一行代码设置和清除不同的位 (C)
【发布时间】:2015-08-05 01:12:30
【问题描述】:

data |= (1 << 3) 设置位 (3) 而不破坏其他位。 data &= ~(1 << 4) 在不中断其他位的情况下重置位 (4)。如何在一条指令中完成这两项任务?

(因为这实际上只是为了可读性,我计划#define以一种可爱的方式#define gpioHigh(x) <insert code>。另一种方法是弄清楚如何正确地将gpio指针传递给我为此专门编写的函数目的,但效果)

谢谢!

迈克

【问题讨论】:

  • Xor 是您的朋友^ 运算符。仅当您想在不知道那里有什么的情况下翻转位时,这才是正确的。否则,设置和重置是确保您确实在设置和重置位的方法。
  • 为什么将 GPIO 指针传递给函数时会出现问题?
  • 语法不通。

标签: c bit-manipulation bitwise-operators firmware


【解决方案1】:

在一条指令中是不可能的。这是因为您需要对不同的位进行 3 种可能的操作:

  • 设置它们(位 3)
  • 清除它们(第 4 位)
  • 别管它们(所有其他部分)

如何使用由二进制数字组成的位掩码从三种可能性中选择一种?

当然,你可以用一行来完成,例如:

data = (data | (1 << 3)) & ~(1 << 4)

【讨论】:

  • 谢谢!我实际上是想要求一个单行字,而不是一个指令......呃。
  • 如果我们选择单行或多行(一个用于设置,一个用于重置),代码大小是否有差异?我猜单行避免了两次读取变量,因此它可能会节省一条读取指令。
  • @Rajesh 这将取决于编译器。但是,我不希望它有所作为。
【解决方案2】:

你不能。

也就是说,如果您想明确确保 bx 设置和 by 清除 - 如果您只想翻转它们(无论先前值如何),您可以与 operator^ 进行异或,正如其他人指出的那样。

要了解为什么不能在一条指令中完成此操作(当然,您可以轻松地将两条或多条指令组合成一条 LOC),请考虑以下真值表:

B|A|Q
-----
0|0|x
0|1|0
1|0|1
1|1|x

“不在乎”xs 与讨论无关。没有逻辑运算符具有此功能 - 怎么可能?如果两个输入的值不同*,我们如何确定哪个是B,哪个是A?这是您问题的核心。

但是,考虑到将其塞进一条指令中可能无论如何都达不到您声明的可读性目标。事实上,如果有的话,这两者分别是更多可读的 - 并且仍然可以被一些set3clear4()调用。


NB - 这与切线相去甚远 - 真值表可以通过 FPGA 架构中所谓的“逻辑元素”来实现,因为它们是由“查找表”(LUT) 构建的,本质上是 ROM,其中输入A,B,... 索引到表中以查找值Q。当然,A¬B 对应的地址与¬AB 不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 2010-09-08
    相关资源
    最近更新 更多