View previous topic :: View next topic |
Author |
Message |
pic_user
Joined: 25 Aug 2005 Posts: 16
|
What is wrong with a nested while loop |
Posted: Fri Aug 26, 2005 6:29 pm |
|
|
I have the following C code:
---------------------------------------------
---------------------------------------------
void detect_key()
{
valid_key = 0;
valid_low = 0;
valid_high = 0;
while (!valid_key)
{
while (!valid_low) detect_low();
while (!valid_high) detect_high();
}
}
---------------------------------------------
---------------------------------------------
When I look at the compiler output I get the following:
---------------------------------------------
111: void detect_key()
112:
113: {
114: valid_key = 0;
0043 01A0 CLRF 0x20
115: valid_low = 0;
0044 01A1 CLRF 0x21
116: valid_high = 0;
0045 01A2 CLRF 0x22
117:
118: while (!valid_key)
119:
120: {
0046 08A0 MOVF 0x20, F
0047 1D03 BTFSS 0x3, 0x2
0048 285A GOTO 0x5a
121: {while (!valid_low) detect_low();}
0049 08A1 MOVF 0x21, F
004A 1903 BTFSC 0x3, 0x2
004B 2849 GOTO 0x49
122: {while (!valid_high) detect_high();}
004C 08A2 MOVF 0x22, F
004D 1D03 BTFSS 0x3, 0x2
004E 2859 GOTO 0x59
0058 284C GOTO 0x4c
123: }
0059 2846 GOTO 0x46
124: }
125:
---------------------------------------------
If you compare the "BTFSS 0x3, 0x2 " in 0047, with the "BTFSC 0x3, 0x2" in 0049 the result is different - and wrong.
Is it illegitmate to have nested while loops? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 26, 2005 6:49 pm |
|
|
How is it wrong ?
The code stays in each loop while the Z flag is set.
It jumps out of each loop when the Z flag is cleared.
I don't know what version of the compiler you have.
I think you want to see cleaner code. The latest
version (PCM vs. 3.232) produces the following code,
which you will probably like better:
Code: |
0000 00336 ... while (!valid_key)
0000 00337 ... {
0021 08A1 00338 MOVF 21,F
0022 1D03 00339 BTFSS 03.2
0023 282B 00340 GOTO 02B
0000 00341 .. while (!valid_low) detect_low();
0024 08A2 00342 MOVF 22,F
0025 1903 00343 BTFSC 03.2
0026 2804 00344 GOTO 004
0000 00345 ..while (!valid_high) detect_high();
0027 08A3 00346 MOVF 23,F
0028 1903 00347 BTFSC 03.2
0029 2809 00348 GOTO 009
0000 00349 ...}
002A 2821 00350 GOTO 021
|
|
|
![](templates/subSilver/images/spacer.gif) |
pic_user
Joined: 25 Aug 2005 Posts: 16
|
Isn't it still wrong? |
Posted: Fri Aug 26, 2005 7:12 pm |
|
|
Here is your code:
----------------------------------------------------------------
0000 00336 ... while (!valid_key)
0000 00337 ... {
0021 08A1 00338 MOVF 21,F
0022 1D03 00339 BTFSS 03.2
0023 282B 00340 GOTO 02B
0000 00341 .. while (!valid_low) detect_low();
0024 08A2 00342 MOVF 22,F
0025 1903 00343 BTFSC 03.2
0026 2804 00344 GOTO 004
0000 00345 ..while (!valid_high) detect_high();
0027 08A3 00346 MOVF 23,F
0028 1903 00347 BTFSC 03.2
0029 2809 00348 GOTO 009
0000 00349 ...}
002A 2821 00350 GOTO 021
----------------------------------------------------------------
Let me highlight the following
0022 1D03 00339 BTFSS 03.2
0025 1903 00343 BTFSC 03.2
0028 1903 00347 BTFSC 03.2
Shouldn't these all be the same, BTFSS 03.2 ?
By the way, I was wrong in what I presented. The output of my compiler - the demo version - actually produced the right code. What happened was that I later invoked the compiler from MPLAB IDE, which is where I got the code I listed originally.
I am totally confused as to why I get different results from the compiler standalone versus from MPLAB, and also why the MPLAB does not give all BTFSS.
And to further complicate it, I don't know what to make of the latest compiler output. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Aug 26, 2005 7:24 pm |
|
|
Quote: | Shouldn't these all be the same, BTFSS 03.2 ? | Nope
Look at what it is doing. Skipping if clear. So if it is set (zero) then goto 4 which is where detect_low() is. |
|
![](templates/subSilver/images/spacer.gif) |
pic_user
Joined: 25 Aug 2005 Posts: 16
|
|
Posted: Fri Aug 26, 2005 7:37 pm |
|
|
Mark,
Yes I agree. But wouldn't the same apply to the first while:
0022 1D03 00339 BTFSS 03.2
0023 282B 00340 GOTO 02B
In other words shouldn't this be BTFSC also? It seems to me that all the while statements should give the same result. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Aug 27, 2005 6:35 am |
|
|
pic_user wrote: | Mark,
Yes I agree. But wouldn't the same apply to the first while:
0022 1D03 00339 BTFSS 03.2
0023 282B 00340 GOTO 02B
In other words shouldn't this be BTFSC also? It seems to me that all the while statements should give the same result. |
Nope, what does it say: Skip if set so in other other if it is zero then skip that goto instruction and execute the while statement below. Just what you wanted. Don't expect every while (0) function to generate the same code. The compiler uses optimization and does what would be the smallest code. Doing it your way would require 2 goto statements. Don't worry about the asm code. Just write your code in C. |
|
![](templates/subSilver/images/spacer.gif) |
|