watch window display of local C variable wrong (Studio 4.13)

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

This is the first time that I've run into this particular problem. The watch window display of a local C variable is incorrect. C compiler used is ImageCraft. Only one local variable is used in this ISR and no optimizations.

Disassembly view shows registers R3:R2 being used to hold local variable values (local variable is "t"). These are loaded from ADC registers in Extended I/O at addresses (0x79:0x78). Values loaded into "t" should be 0x01:0xDF or 479 dec. Watch window shows t = 1793 and location is 0x04EB ???

I know that code optimizers try to reused registers for different local variables, but in this instance, this shouldn't be a factor.

Any similar experiences ?

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Screen snapshot got deleted because of size.
Here is reduced version.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you need to think about how the watch window actually works here.

All that happens is that the watch window "knows" that 't' is a 16 bit variable
and that it is located at 0x4EB (and 0x4EC) so to give you a view of the
variables contents then each time the debugger stops it takes the value in
0x4EB (low byte) and 0x4EC (high byte) and combines that to show you the 'value'
that's currently held there. For decimal 1793 to be display it suggests that as
the simulator stopped with PC=0x620 that 0x4EB was containing 0x01 and 0x4EC
was containing 0x07. Nothing more, nothing less.

Now look at the code you just stepped over:

LDS R2, 0x0078
LDS R3, 0x0079

OK so that has retrieved the ADC value from ADCL and ADCH but so far the reading
has got no further than R3:R2. Only if the code went on to:

STS 0x4EB, R2
STS 0x4EC, R3

would the watch window THEN show you the value that was in ADC and that has passed
through R3:R2.

As it stands this simply looks like compiler optimisation in action. I'll bet 't' is
not actually accessed further in the function so the compiler see no need to waste
operations to store it into SRAM.

Try either (a) making 't' volatile in which case you will see the STS instructions
added to comit it back into SRAM or (b) turn off any form of optimisation for
the entire program. In this case ALL the variables will be STS'd into SRAM after
each modification to them.

Cliff

(PS This proves once again how crap "watch windows" actually are. You are far better recognising
that R3:R2 is being used for 't' and simply to keep an eye on the contents of those two registers)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code optimizer is turned off and "t" is defined as volatile - No change to result.

The variable "t" should not be stored in SRAM at all. It is local variable, only one local variable is used, and plenty of registers are available. In this ISR, SRAM was not accessed at all. Another thing that is odd, is that this SRAM location is right below the hardware stack. If the complier was using this for temporary storage, it should have used a pointer to a software stack. Maybe this SRAM location is the top of the software stack where variables "could" be stored if needed in case all of the registers had been used ?

I think the problem lies with the COFF file, or how Studio interprets the COFF file. Apparently, Studio or COFF cannot recognize when a variable is stored in a register(s). I know for certain that the present implemention of Studio will not recognize a global variable that is defined as a fixed register.

Although I can read the disassembled code and figure out where the compiler has put things, the whole purpose of having symbolic debug is so we don't have to go poking around in the disassembly view too often.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well if it's only ever optimised into a register there is no way the watch window will
ever work to view it then. Re-read my description above of how the watch window works.
It's not performing miracles, it's simply giving you a "structured view" of what is in
SRAM locations. It won't give you a view of what is not in SRAM. Perhaps the fault here
is that the debugger should never have allowed you to add 't' to the watch window in
the first place?

(the situation would have been the same whether this was ELF or COFF. The generated code
only ever holds 't' in R3:R2 so it cannot be watched and no debugging format would
make it otherwise)

Cliff