| 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?
 |  | 
	
		|  | 
	
		| 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
 
 | 
 |  | 
	
		|  | 
	
		| 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.
 |  | 
	
		|  | 
	
		| Mark 
 
 
 Joined: 07 Sep 2003
 Posts: 2838
 Location: Atlanta, GA
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Fri Aug 26, 2005 7:24 pm |   |  
				| 
 |  
				| Nope 	  | Quote: |  	  | Shouldn't these all be the same, BTFSS 03.2 ? | 
 
 Look at what it is doing.  Skipping if clear.  So if it is set (zero) then goto 4 which is where detect_low() is.
 |  | 
	
		|  | 
	
		| 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.
 |  | 
	
		|  | 
	
		| 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.
 |  | 
	
		|  | 
	
		|  |