Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I wanted to replace bit/bits(more than 1) in a 32/64 bit data field without affecting other bits.Say for example:

I have a 64 bit register where bits 5&6 can take values 0,1,2,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&6 modified.(so it become 126 after changing)

I tried doing this

reg_data=0x146 reg_data |= 1 << shift   (shift in this case is 5) 

If i do this value at bit positions 5& 6 will become 11(0x3) not 01(0x1) which i wanted.

  • How do i go about doing read/modify/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.

Any suggestions are highly appreciated.

like image 621
Unicorn Avatar asked May 08 '11 05:05

Unicorn


People also ask

How do you replace a bit in a number?

Fetch the jth bit from the num2 and ith bit from num1 by using xor = ((num1 >> i) ^ (num2 >> j)) & 1; 4. Now replace the ith bit in num1 with that of jth bit in num2 by using res = num1 ^ (xor << i) ^ (xor ^ j);

Which macro clears the nth bit in a byte by keeping other bits unchanged?

Clearing bit using macro: We use the bitwise AND operator (&) to clear a bit. x &= ~(1UL << pos); it will clear nth bit.

Which logic operation is used for setting a bit without modifying other bits?

For example, this is necessary to change settings in the microcontroller or other devices. We use bitwise operators to change certain bits while not affecting others.


1 Answers

Why don't you use a bitmask? 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.

like image 56
vy32 Avatar answered Oct 11 '22 01:10

vy32