|
|
View previous topic :: View next topic |
Author |
Message |
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
Simple C Syntax " |= " not working |
Posted: Fri Jan 18, 2008 3:30 am |
|
|
Hi everybody,
I was wondering what is the difference between this 2 lines:
Code: | *xBufEvent = *xBufEvent | 0x01; |
and
Code: | *xBufEvent |= 0x01; |
For me they have to do the same thing but the second one is not doing anything...
Thanks for any reply,
Franck. |
|
|
Ttelmah Guest
|
|
Posted: Fri Jan 18, 2008 4:09 am |
|
|
Hm.
It generates correct code in either case for me...
What compiler version?.
The simple version, generates (fo a 16chip):
Code: |
.................... *xBufEvent |= 0x01;
006C: MOVF 2D,W
006D: MOVWF 04
006E: BCF 03.7
006F: BTFSC 2E.0
0070: BSF 03.7
0071: MOVF 00,W
0072: IORLW 01
0073: MOVWF 00
|
Which (in this case xBufEvent is stored in location '0x2D', and '0x2E'), puts the contents of 2D, into the indirect addressing register, uses the contents of 2E to set the page register, then retrieves the byte addressed by these, bitwise OR's it with 1, and writes it back.
While for a 18F chip, it generates:
Code: |
.................... *xBufEvent |= 0x01;
00E4: MOVFF 1C,FE9
00E8: MOVFF 1D,FEA
00EC: MOVF FEF,W
00EE: IORLW 01
00F0: MOVWF FEF
|
Which again is correct (xBufEvent is stored here in 1C/1D).
The same correct code, is generated by 3.249, and 4.066 compilers.
There is a 'caveat' about this type of statement, in that it is preferred, and safer, to use:
(*xBufEvent) |= 0x01;
since otherwise there an be precedence problems with some commands a the '*' (this is mentioned in K&R, at a couple of places), but this shouldn't apply with what you post.
Best Wishes |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Fri Jan 18, 2008 6:51 am |
|
|
Thanks for your reply,
I'm using PCD 4.066 for a pic24H.
I hyaven't had a look of the asm code that my compiler have generated .
I will check that this night.
Thanks. |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Fri Jan 18, 2008 10:10 am |
|
|
I tried this just for fun using my ancient compiler, adding it as a line in an existing program using a variable that I already had defined. I'm utterly puzzled by this result. My variable is at 0x57, but what's all this use of 0x37 and 0x38? I don't get it at all.
But I'm certain that the quickest way to do what Franck wanted would be
Code: |
bit_set(*xBufEvent, 0);
|
Code: |
0000 03116 .................... *cons0 = *cons0 | 0x01;
0726 0857 03117 MOVF 57,W
0727 1683 03118 BSF 03,5
0728 00B7 03119 MOVWF 37
0729 1283 03120 BCF 03,5
072A 0857 03121 MOVF 57,W
072B 0084 03122 MOVWF 04
072C 0800 03123 MOVF 00,W
072D 3801 03124 IORLW 01
072E 1683 03125 BSF 03,5
072F 00B8 03126 MOVWF 38
0730 0837 03127 MOVF 37,W
0731 0084 03128 MOVWF 04
0732 0838 03129 MOVF 38,W
0733 0080 03130 MOVWF 00
0734 1283 03131 BCF 03,5
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Jan 18, 2008 10:36 am |
|
|
Temporary variables.
It takes the contents of 57, and temporarily stores it in 37. Then writes it to the indirect addressing register. Takes the location addressed by this, and performs the OR, stores the result of this into 38, then brings back the temporary value in 37, and again writes this to the address register, and writes to result from 38, to the addressed location.
Effectively it treats it as two halves (because of the layout), and performs the right hand part first, to the temporary registers, then the left hand part using the values from this.
I must admit, I'd not be suprised if there was a problem with this on the 24F chips. Read the comments here about V4, and realise it took CCS, a year to actually produce a reasonably 'working' V4. Then think how long support for the 24F chips has existed. At present, it is closer to working than V4 was at the same point, but I'd definately consider the 16bit compiler to be 'beta'...
Best Wishes |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Fri Jan 18, 2008 2:02 pm |
|
|
OK, shame on me, it was that my watches were not refresh on time with my debugger ...
But I still have the same kind of problem...
This code is working:
Code: | static unsigned int _FCT_EV_Mask;
void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
_FCT_EV_Mask = 1;
_FCT_EV_Mask <<= NumEvent;
(*xBufEvent) |= _FCT_EV_Mask;
} |
And this one not:
Code: |
static unsigned int _FCT_EV_Mask;
void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
_FCT_EV_Mask = 1;
(*xBufEvent) |= (_FCT_EV_Mask << NumEvent);
} |
In fact I wanted to use the second one cos I've noticed in the lst file of the first one that the code is not very efficient : the result of "_FCT_EV_Mask <<= NumEvent" is put from W0 to _FCT_EV_Mask and put back from _FCT_EV_Mask to W0...
The asm code of the first one which is working:
Code: | void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
*
00200: MOV W5,[W15++] : Push W5 to TOS
.............................. _FCT_EV_Mask = 1;
00202: MOV #1,W4 : W4 = 1
00204: MOV W4,85C : [85C] = W4
.............................. _FCT_EV_Mask <<= NumEvent;
00206: MOV 872,W4 : W4 = [872]
00208: MOV 85C,W0 : W0 = [85C]
0020A: SL W0,W4,W0 : W0 = W0 << W4
0020C: MOV W0,85C : [85C] = W0
.............................. (*xBufEvent) |= _FCT_EV_Mask;
0020E: MOV 870,W5 : W5 = [870]
00210: MOV [W5],W0 : W0 = [W5]
00212: IOR 85C,W0 : W0 = [85C] | W0
00214: SUB.B W5L,#2,W5L : W5L = W5L - 2
00216: MOV.B W5L,[W5] : [W5] = W5L
00218: MOV.B #0,W0L : W0L = 0
0021A: MOV.B W0L,[W5+#0] : [W5+0] = W0L
.............................. }
0021C: MOV [--W15],W5 : POP TOS to [--W15]
0021E: RETURN : Return
} |
And the asm code of the second one which is NOT working:
Code: | void SetEvent(unsigned int *xBufEvent, unsigned int NumEvent)
{
*
00200: MOV W5,[W15++] : Push W5 to TOS
.............................. _FCT_EV_Mask = 1;
00202: MOV #1,W4 : W4 = 1
00204: MOV W4,85C : [85C] = W4
.............................. (*xBufEvent) |= (_FCT_EV_Mask<<NumEvent);
00206: MOV 870,W5 : W5 = [870]
00208: MOV 872,W4 : W4 = [872]
0020A: MOV 85C,W0 : W0 = [85C]
0020C: SL W0,W4,W0 : W0 = W0 << W4
0020E: IOR W0, [W5],W0 : W0 = W0 | [W5]
00210: SUB.B W5L,#2,W5L : W5L = W5L - 2
00212: MOV.B W5L,[W5] : [W5] = W5L
00214: MOV.B #0,W0L : W0L = 0
00216: MOV.B W0L,[W5+#0] : [W5+0] = W0L
.............................. }
00218: MOV [--W15],W5 : POP TOS to [--W15]
0021A: RETURN : Return
} |
Did someone have an idea why this 2 codes are not doing the same thing?
And I haven't catch what is the purpose of this line:
Code: | 00210: SUB.B W5L,#2,W5L : W5L = W5L - 2 |
Thanks for any helps,
Franck. |
|
|
Bob Sacamano
Joined: 17 Jan 2008 Posts: 16 Location: Somewhere Cold, USA
|
|
Posted: Fri Jan 18, 2008 2:18 pm |
|
|
The two code snippets are not the exact same thing. In the first one, _FCT_EV_Mask has it's value updated after left-shifting. In the second one, the variable will never be updated, it will only be used in determining the value to store at xBufEvent.
What exactly is happening that is wrong?
Can you post a small, complete, compilable example program that shows the error. Include what you expect the results to be and what they actually are. _________________ "And you want to be my latex salesman." |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Sat Jan 19, 2008 9:26 am |
|
|
Thanks for your reply,
I've found what was my problem, it was the pointer.
It seems that the compiler is not doing the same thing for this 2 lines of codes:
Code: | (*ptrResult) |= Mask; |
is not the same that
Code: | (*ptrResult) = (*ptrResult) | Mask; |
The first code is changing only the pointer, and the second one is changing the variable pointed by ptrResult (it's what I wanted).
I don't know if it's a bugg in the compiler or if it's normal... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|