I've filed this with Microchip. Until a fix is released, the following may help.
There seems to be a reproducible error in Set Next Statement. The following are affected; I haven't checked other scenarios and don't plan to:
- new install of the latest Microchip Studio 7.0.2542 with all updates
- both the Disassembly window and the PC in the Processor Status window
- debugging mixed C/assembler running on the simulator
- builds for ATtiny214, 414 and 416, all with avr-gcc and no optimisation.
Starting then pausing a debug session (typically with Start Debugging and Break) should let you:
- open the debugger's Disassembly and/or Processor Status window
- prepare to depart from the normal execution path, by either:
- right-clicking an instruction, its address or byte contents in the Disassembly window, then choosing Set Next Statement
- typing the word address of an instruction into the Processor Status window's Program Counter, then pressing <Enter>.
- If you chose to set the PC, it should reflect the word address which you entered for the new statement - the "target statement".
- If instead you used Set Next Statement in the Disassembly window:
- the yellow arrow in the margin, which indicates the next statement, should be repositioned to the target statement which you chose
- if you drop down the Viewing Options at the top and ensure "Show address" is ticked, the word address of the target instruction should be shown.
What happens instead is that either:
- if you used the PC, what it now shows as a word address is in fact the byte address corresponding to the word address that you typed in
- if you used Set Next Statement in the Disassembly window, the next statement is at twice the word address of the statement you chose.
That is, by either method the next statement will be set incorrectly to twice the address of the target statement that you chose.
Suppose for example that you wish to continue executing from a statement at word address 0x0462:
- If you type 0x0462 into the PC and press <Enter>:
- the PC will instead show 0x08C4
- (assuming an instruction exists there) single-stepping the debugger will show that indeed execution continued from 0x08C4 not from 0x0462.
- If instead you browse the Disassembly window to an instruction at word address 0x0462 and Set Next Instruction on it:
- the yellow "next instruction" arrow will relocate to an instruction at 0x08C4 (assuming one exists)
- single-stepping the debugger will show that indeed execution continued from there, not from the instruction you chose at 0x0462.
- If you use the PC method, the Disassembly window (including its "next instruction" arrow) won't be resynced with the new (incorrect) PC until you execute a statement (e.g. by single-stepping).
- If you use the Disassembly window, the "next instruction" arrow will only reposition to twice the chosen word address if your code extends that far. If it doesn't - if, say, in the above example there's no code at 0x08C4 - then the arrow may reposition to some seemingly random address. (The reset vector at 0x0000 is common but so are random addresses containing only NOPs.)
The nub of the problem is that, somewhere between the debugger and simulator, word and byte addresses are confused with each other. An obvious workaround is to choose a target instruction whose word address is half that of the one you wish to execute from. The bug will misinterpret the byte address of that instruction as a word address; as the next instruction, it will then assign whatever has that number as its word address. Thus by a roundabout route you will end up choosing the instruction that you intended.
Using the above example: to continue from the instruction at word address 0x0462, to work around the bug we must choose an instruction with 0x0462 as its byte address. The corresponding word address is of course half that: 0x0231. You can choose that by either:
- entering 0x0231 into the PC
- browsing to an instruction at word address 0x0231 in the Disassembly window, then choosing Set Next Instruction on it.
This won't always be so straightforward:
- The instruction you wish to execute from may have an odd-numbered word address; clearly that can't be halved for the workaround.
- Some instructions are longer than one word, so there may be no instruction at the address you need to choose as a workaround - instead the address may be straddled by an instruction.
In such cases, choose an instruction that will be executed slightly before the one you need, then either single-step to the intended target instruction or set a breakpoint on it.