How to replace bits in a bitfield without affecting other bits using C

bit-manipulation, c

Solution

Use a bitmask. It is sort of like:

new_value = 0, 1, 2 or 3  // (this is the value you will set in)
bit_mask = (3<<5)         // (mask of the bits you want to set)
reg_data = (reg_data & (~bit_mask)) | (new_value<<5)

This preserves the old bits and OR's in the new ones.

Problem

I wanted to replace bit/bits (more than one) in a 32/64 bit data field without affecting other bits. Say for example: I have a 64-bit register where bits 5 and 6 can take values 0, 1, 2, and 3. ``` 5:6 --- 0 0 0 1 1 0 1 1 ``` Now, when I read the register, I get say value 0x146 (0001 0 10 0 0110). Now I want to change the value at bit position 5 and 6 to 01. (Right now it is 10, which is 2 in decimal, and I want to replace it to 1 e 01) without other bits getting affected and write back the register with only bits 5 and 6 modified (so it becomes 126 after changing). I tried doing this: ``` reg_data = 0x146 reg_data |= 1 << shift // In this case, 'shift' is 5 ``` If I do this, the value at bit positions 5 and 6 will become 11 (0x3), not 01 (0x1) which I wanted. - How do I go about doing read, modify, and write? - How do I replace only certain bit/bits in a 32/64 bit fields without affecting the whole data of the field using C? Setting a bit is okay, but more than one bit, I am finding it little difficult.

Original source

Related problems