Continue to Site

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
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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top