Atmel Studio 6.2 - Weird Compare Condition Behaviour

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Was getting strange behaviour on return from
 

DSTATUS disk_initialize (void)

So as shown below, after the return from disk_initialize, the return value is compared to zero. If equal then the condition is entered.
However it seems to never compare the return to zero, rather to 0x9F (contents of R01), and the  if (res==0x00) condition is never entered. I’m a bit confused as to what is going on.
Am debugging a 328p via debug wire (Atmel Dragon). Optimisation is –Os, but the same thing happens with –O1. Also res is declared volatile.  Edit - forgot to say the code runs in the bootloader section, but the code size easily fits.

 

 

Last Edited: Fri. Jul 31, 2015 - 04:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure of the point you are making. The GCC ABI takes the first function parameter into a function in R25;R24 and similarly it returns the result in R25:R24 (R24 only significant of the two if its 8 bits). So at 3858 in your code it calls 39DA and then that comes back with "res" in R24. Similarly the GCC compiler always holds 0x00 in R1 (and puts it back after anything that might disturb that). So the code is:

00385A CPSE R24, R1

That's a valid comparison of "res" with 0x00 isn't it? CPSE is a "compare, skip if equal". So when res=0x00 it skips to 385C. Otherwise it takes the RJMP to PC+00FD.

 

EDIT: Oh I see the point you are making - at the time of the comparison __zero_reg_ (as GCC calls R1) is holding 0x9F not 0x00 as it should be. That suggests that either something in dosk_initialize() damaged it or, more likely there's some interrupt code at work here that has used R1 without putting 0x00 back when it was finished.

 

Does this project contain any ISR written in Asm by any chance. If it uses R1 (such as using MUL) then does it ensure it is pout back to 0x00 before RETI? (this is an absolute requirement of GCC- you MUST ensure R1 always has 0x00 when running compiler generated code - it just assumes it always holds 0x00. As I say it knows it as __zero_reg__ and is a quick access 0x00 byte for its internal work.

Last Edited: Fri. Jul 31, 2015 - 05:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Does this project contain any ISR written in Asm by any chance. If it uses R1 (such as using MUL) then does it ensure it is pout back to 0x00 before RETI? (this is an absolute requirement of GCC- you MUST ensure R1 always has 0x00 when running compiler generated code - it just assumes it always holds 0x00. As I say it knows it as __zero_reg__ and is a quick access 0x00 byte for its internal work.

Thanks, put me on the right track. Embarassingly the problem was caused by commented out code (though the prog. somehow has worked with this). Even more embarassingly the problem, caused by -nostartfiles is described in detail...

register uint8_t myR1 asm("r1"); // just doing this so I can do the normal CRT stuff (R1=0, SREG=R1)

    // because -nostartfiles is used there is no CRT so nothing to ensure R1=0, clear SREG
    // setup the stack pointer and so on. The following therefore replaces those things from
    // the standard CRT. Note there is no .data or .bss usage in this program so no need to 
    // duplicate those loops.
	
    myR1 = 0;    //No Start Files breaks debug wire watch variables.
    SREG = myR1;
    SPH = RAMEND >> 8;
    SPL = RAMEND & 0xFF;