位操作,不必要的掩码?

时间:2017-03-14 16:16:40

标签: c bit-manipulation bit-shift

我试图在嵌入式c编程中保持位操作。

我有以下代码

#define X_POS       (8UL)
#define X_MASK      (0x1FUL<<X_POS)
#define Y_POS       (16UL)
#define Y_MASK      (0x3UL<<Y_POS)

typedef struct {         
    uint32_t  res[6];  
    uint32_t  config[10];                            
} myStruct_type;

myStruct_type myStruct;

void configure (uint32_t n, uint32_t x, uint32_t y)
{
    myStruct.config[n] &= ~(X_MASK | Y_MASK);     // A
    myStruct.config[n] |= ((x<<X_POS) & X_MASK) | ((y<<Y_POS) & Y_MASK);  // B
}

int main (void)
{
    configure(3, 18, 2);

    while (1) { }
}

我理解标有注释A的行用于将感兴趣的位设置为0,即清除这些位。

另外我理解在标有B的行上,感兴趣的位被设置为想要的值。

但是B线上X_MASK和Y_MASK的目的是什么? Aren是

设置的值
(x<<X_POS) | (y<<Y_POS)

2 个答案:

答案 0 :(得分:3)

B行屏蔽的目的是确保只设置您想要设置的位。例如如果x为0xFFFFFFFF,则带有&的{​​{1}}将停止高于您感兴趣的位置。

所以假设config [0]从0开始,x是0xFFFFFFFF,y是0,没有maskingin行B,你会有

X_MASK

使用蒙版,第二行是

myStruct.config[0] &= ~(X_MASK | Y_MASK);     // config[0] is still 0
myStruct.config[0] |= (0xFFFFFFFF << 8) | (0<< 16);  
// config[0] is now 0xFFFFFF00 

 myStruct.config[0] |= ((0xFFFFFFFF<< 8) & 0x1F00) | (( 0 << 16) & 3 << 16);  // B

答案 1 :(得分:0)

如果您只使用(x<<X_POS) | (y<<Y_POS),则只需将值xy分配到左侧。

掩码消除了不需要的位。例如:

X_MASK = 0x1FUL << 8UL = 0x1F00000000 = 0b111110000...

使用逻辑&amp; (AND)你将掩码上的所有位设置为零:

X_MASK     0b00000001111100000000.....
x<<X_POS   0b01010101010100000000.....
&          ________________________
result     0b00000001010100000000.....

在更高级别上,您可以说,X_MASKx的所有位设置为零,除了最低5和Y_MASKy的所有位设置为0零,除了最低2.然后你的结果被移位到左边。因此掩码将清除更高的位。