This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

stmdb instruction *appears* not to work correctly - Cortex M4 / SAM4L

I'm struggling to track down a problem here. It appears to be that the stmdb instruction isn't pushing all of the requested registers, and when the corresponding ldmia.w instruction executes, it pops a PC value that sends the processor executing code from RAM.

I'm using GNU MCU Eclipse tools for development, with SEGGER debugging. My target is a SAM4L from Microchip.

arm-none-eabi-gcc (GNU MCU Eclipse ARM Embedded GCC, 64-bit) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]

I can single-step over the offending instruction, and I can't see that it is doing what it says it should.

The offending instruction is executed on entry to a function. The previously executed instruction is the call to the function "bl 0x3b38".

0003b38: stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}

Before executing this instruction SP has the value 0x20001b88. After using the debugger to single-step over this instruction SP has the value 0x20001b74. 

Examining the stack memory shows that registers  R12, R11, R10, and R9 were pushed to locations 0x20001b80 through 0x20001b74 respectively. Location 0x20001B84 gets the value that is in the PC *after* the instruction executed 

I've examined the memory location where the Assembly instruction is stored, and it appears to be coded correctly, with R3-R11 and LR (=R14) coded. The destination register is 0b1101 = Stack Pointer.

00003b38: 2DE9F84F

     E9    |   2D   |   4F   |   F8
=> 11101001 00101101 01001111 11111000 

At the end of the called function, the "pop" instruction appears to work as advertised, loading a RAM address into the PC. Things don't go well from here on.

I've attached Debugger Screenshots from Before and after the step through the offending instruction illustrating my comments above.

Any clues what is happening here would be greatly appreciated.

Thanks,

  • OK, With some help from @old_timer and @fuz on stack exchange, I've got to the bottom of this.


    It was a problem with the debugger. When I used the Eclipse MCU debugger to view the instruction it showed 0xE92D4FF8. When I used another debugger (J-Link) to view the instruction, it showed 0xE92DBE00.

    The Eclipse MCU debugger is able to write breakpoints to Flash when it runs out if hard breakpoints on the controller. 0xBE00 corresponds to the BKPT instruction, so it looks like a breakpoint instruction was written over the top of the low 16 bits of the STMDB instruction.

    It appears that the Eclipse MCU debugger somehow lost track of that breakpoint, and left the modified instruction in Flash. A full Erase (from J-Link) and reprogram, and everything is now working the way it should.