This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5529: Branch to indirect address uses 20 bits for MSP430x when debugging

Part Number: MSP430F5529

Hello! For my application, I'm trying to jump back to the address stored in the reset vector 0xFFFE. I'm using `asm("    BRANCH &0xFFFE")` to do so. This seems to work alright in normal operation, but if I pause execution before the instruction and try to step through (like I was when trying to verify it works), the PC is always loaded with 20 bits from the memory at _reset_vector instead of 16. This is the case even if I skip the emulation instruction and use `MOV.W` directly. For example, with the memory below, I would expect the PC to be loaded with 0x06EAE, but it is loaded with 0xF6EAE instead. This only occurs when I pause execution at or just before the branch instruction. If I am simply connected to the debugger and start running from main, there is no issue. This is not the first time I have been burned by this behavior; am I missing something here? Why would a branch instruction load a 20-bit PC even with small code model?

  • Using `asm volatile` instead seemed to solve this....not sure why. Some insight would be appreciated.

  • Hi Jacob,

    The volatile keyword fixing this points to potentially the compiler being the source of the issue. Which compiler/IDE are you using? 

    If CCS, can you go to View -> Dissassembly while debugging, and see what the actual assembly instructions look like in both cases? 

    Best Regards,
    Brandon Fisher

  • I don't see a "BRANCH" mnemonic. Just "BR" and "BRA". The first always clears the upper 4 bits while "BRA" is the extended version.

  • Section 6.6.2.8 of the MSP430x5xx user guide is titled "BR, BRANCH", and for other opcodes that is the mnemonic. I took this to mean that either "BR" or "BRANCH" will "Branch to destination in lower 64k address space". I believe I tried all three of "BR" "BRA" and "BRANCH" and had the same results.

  • I'm using CCS. When debugging with no volatile, It shows `BR &_reset_vector` with opcodes `0x0200 0xFFFE`. With volatile it is the same mnemonic but opcodes `0x4210 0xFFFE`

  • Opcodes beginning with a zero like 0x0200 are a MOVA instruction and thus 20 bits. Those starting with a four are MOV.

    Why the use of volatile is changing things I don't know. With the GNU compiler it disables some optimizations that could cause trouble. Or so says the docs.

    I tried this with GCC and checked the output. BRANCH it didn't like, BR generated a MOV, and BRA a MOVA. All without a volatile tag.

  • It looks to me then this is just a nuance related to how the compiler is optimizing this code. I will see if our tools team can comment.

    I don't necessarily expect the compiler to be optimizing inline assembly statements (unless it determines they are unreachable), but my expectation may be incorrect here. 

    Best Regards,
    Brandon Fisher

  • For the source file with the problem asm statement, please follow the directions in the article How to Submit a Compiler Test Case.  After you have created the preprocessed file, add a comment that shows the asm statement in the form where it works, i.e. with volatile.

    Thanks and regards,

    -George

**Attention** This is a public forum