how can in get one bit and copy it to specific location in another byte

Status
Not open for further replies.

Micro Lover

Member level 2
Joined
Jul 22, 2009
Messages
44
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
pakistan
Activity points
1,614
hi
i have two variable

unsigned char x = 170; // 10101010

unsigned char y = 255; // 11111111

now i want to copy the 3rd bit of x (Bold) to the 6th bit of y (underlined)

in keil 4.10, portable using C

how can i do it?
 

Code:
y= (y & 223) | ((x & 4)<<3)

y & 223 clears to 0 the bit that you want to write

x & 4 clears all the bits except the one that you want to read
<<3 moves the bit you read to the bit you want to write

Alex
 
An other (maybe shorter and faster) solution:

Code:
y &= b11011111;       // the 6th bit of y is cleared (zeroed) first
if (x & b00000100)    // mask for the 3rd bit of x, if it is not zero then:
   y += b00100000;    // set the 6th bit of y
 

Actually it seems to take more instructions, at least when 1 is going to be written but less instructions when read value is 0.
Tested in Uvision 4.5 , LPC1788


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
1545: y= (y & 223) | ((x & 4)<<3); 
0x00001486 4608      MOV      r0,r1
0x00001488 6800      LDR      r0,[r0,#0x00]
0x0000148A F00000DF  AND      r0,r0,#0xDF
0x0000148E 490F      LDR      r1,[pc,#60]  ; @0x000014CC
0x00001490 6809      LDR      r1,[r1,#0x00]
0x00001492 F0010104  AND      r1,r1,#0x04
0x00001496 EA4000C1  ORR      r0,r0,r1,LSL #3
0x0000149A 490D      LDR      r1,[pc,#52]  ; @0x000014D0
0x0000149C 6008      STR      r0,[r1,#0x00]





Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1547: y &= 223;       // the 6th bit of y is cleared (zeroed) first 
0x00001486 4608      MOV      r0,r1
0x00001488 6800      LDR      r0,[r0,#0x00]
0x0000148A F00000DF  AND      r0,r0,#0xDF
0x0000148E 6008      STR      r0,[r1,#0x00]
  1548: if (x & 4)    // mask for the 3rd bit of x, if it is not zero then: 
0x00001490 480F      LDR      r0,[pc,#60]  ; @0x000014D0
0x00001492 6800      LDR      r0,[r0,#0x00]
0x00001494 F0100F04  TST      r0,#0x04
0x00001498 D003      BEQ      0x000014A2
  1549:    y += 32;    // set the 6th bit of y 
0x0000149A 4608      MOV      r0,r1
0x0000149C 6800      LDR      r0,[r0,#0x00]
0x0000149E 3020      ADDS     r0,r0,#0x20
0x000014A0 6008      STR      r0,[r1,#0x00]



Alex
 
You are absolutely right, Alex, but not all microcontroller have multi-shift instructions like your ARM (here: ORR r0,r0,r1,LSL #3) ;-)
 

I only did it out of curiosity, not to prove that my code is better or anything.
The OP mentioned Uvision and I assumed ARM but maybe it is a C51 target.
I just wrote the first solution that came to my mind.

Alex
 
Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…