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.

Auto-increment with R3 as destination

Other Parts Discussed in Thread: MSP430F449, MSP430G2452

Needing to to increment R8 without affecting the carry flag, this line was coded.

MOV.W  @R8+, R3

No error or warning was generated by the assembler (CCS) .  When executed on an msp430f449, auto-increment  did not happen.  Changing to this worked.

MOV.W  @R8+, R12

Using R3 (CG2) as the destination seams to prevent the incrementing.  Can anyone shed some light on this behavior?

R. Harkins

  • I am working with (IAR) MSP430 assembler. Never used CG2 directly (by instruction) in code, and guess that it can't be used simple as general purpose set (R4 - R15).

  • zrno soli said:

    I am working with (IAR) MSP430 assembler. Never used CG2 directly (by instruction) in code, and guess that it can't be used simple as general purpose set (R4 - R15).

    Have you seen this? It is on Page 82 of SLAU144I.PDF

    Example The eight-digit BCD number contained in R5 and R6 is added decimally to an eight-digit BCD number contained in R3 and R4 (R6 and R4 contain the MSDs).

    CLRC ; clear carry

    DADD R5,R3 ; add LSDs

    DADD R6,R4 ; add MSDs with carry

    JC OVERFLOW ; If carry occurs go to error handling routine

  • R3 is the second half of the constant generator. Any read from R3 will result in one of the predefined constants, depending on the used addressing mode. So writing to it (or using it to index a destination memory address) makes no sense and is an illegal operation. I guess the whole instruction with R3 as destination isn't executed at all. Including the auto-increment.

    From users guide:

    "Registers R2 and R3, used in the constant mode, cannot be addressed explicitly; they act as source-only registers."

    Exception: in register mode, R2 acts as a normal register, the status register. This is addressed by the 'in constant mode' term, which is true for all but R2 in register mode.

    It should be added to the users guide that apparently instructions with R3 as destination won't be executed. Whcih normally makes no difference except if reading the source has a side-effect (like clearing an interrutps) or auto-increment mode is used.

  • Is this a mistake?  If it is not, please explain. 

    R. Harkins

  • (Sorry to double post.  The first one is not clear on what I was referring to.)

    CLRC ; clear carry

    DADD R5,R3 ; add LSDs

    DADD R6,R4 ; add MSDs with carry

    JC OVERFLOW ; If carry occurs go to error handling routine

    Is the use of R3 a mistake?  If it is not, please explain. 

    R. Harkins

  • The idea that an instruction with R3 as a destination is not executed fits.  My thought was the it did not complete and therefore skipped the auto-increment.

    For those that may find this thread in the future:  The situation is doing a string of additions with carry in a loop and wanting auto-increment on both source and destination.  Lacking auto-increment on destination, a second operation writing to R3 was tried.  The solution will be to use a more conventional increment.  The carry flag for the main addition will be preserved by pushing and popping the status register.

     Thanks,

    R. Harkins

  • In at least two TI publications (slau056k, slau144i) the NOP is documented with the emulation

    MOV #0, R3

    It consumes 1 cycle and 1 word of memory.

    Writing to R3 appears to be valid.  As already pointed out, side-effect  may not work.

  • I did an experiment with MSP430G2452 (I do not have any MSP with CPUXv2).

    The result here is the same: MOV.W/.B @R8+, R3 does not modify R8. Interestingly, the instruction executes in 1 clock cycle instead of 2 (measured by reading TA0R before and after a block of instructions), so the read seems to be not performed at all. (However, in IAR Simulator, the instruction executes as one could expect., R8 is incremented.)

    I tried also MOV.W &TA0IV, R3 (reading a read-sensitive peripheral register). The read was clearly not performed as the side effect was not seen. I did not measure clock cycles here.

    Anyway, using R3 as destination is apparently really undefined (except of NOP = MOV.W R3, R3) and seems to be rather useless.

    Michal

  • MOV #0,R3; MOV R3,R3; NOP; all generate exactly the same machine code that takes 1 MCLK to do nothing.

    Try MOV.B 0x3FFE(R8),R3; This one takes a lot longer to do nothing ;)

    --OCY

  • Namely, eternity? ;-)  Nice finding! Same as MOV.B 0x3FFF(R8), R3.

    It looks like using R3 as destination results in interpreting the instruction as single-word, independent of the actual addressing mode for the source operand. This way the following address word of 0x3FFE or 0x3FFF is interpreted as JMP $-4 or JMP $-2 opcode which cause infinite loop. 

    It might be a trick for code obfuscation and making it harder to single-step with a debugger ;-) I have seen similar tricks in 6502 and x86 programs, but here, there is hardware protection with security fuse anyway.

    Michal

  • Robert Harkins said:
    Writing to R3 appears to be valid.  As already pointed out, side-effect  may not work.

    Well, since there is no 'invalid instruction' exception, and the instruction won't have any effect, you don't know whether it is valid or not, whether it is executed or ignored. It's a single-instruction-word instruction that takes one CPU cycle. And whether it is to be executed or ignored can of course only determined after reading it, which takes this one CPU cycle. :)

    Michal H. Tyc said:
    The result here is the same: MOV.W/.B @R8+, R3 does not modify R8. Interestingly, the instruction executes in 1 clock cycle instead of 2 (measured by reading TA0R before and after a block of instructions), so the read seems to be not performed at all. (However, in IAR Simulator, the instruction executes as one could expect., R8 is incremented.)

    Interesting. The simulator apparently didn't catch that R3 is read-only and treats it as a normal instruction. What does the simulator say about R3 content? (Which should depend on read mode and always return 0 when read in register mode)

    Michal H. Tyc said:
    I tried also MOV.W &TA0IV, R3

    But apparently the instruciton is caried out at least as far as needed to read or skip the TAIV immediate value right after the instruction.

    Michal H. Tyc said:
    Anyway, using R3 as destination is apparently really undefined (except of NOP = MOV.W R3, R3)

    Well, it makes no difference, if the NOP is ignored or executes somehting that hasn't any effect and takes the same time to execute :)

    Michal H. Tyc said:
    and seems to be rather useless.

    Indeed.

    old_cow_yellow said:
    MOV #0,R3; MOV R3,R3; NOP; all generate exactly the same machine code that takes 1 MCLK to do nothing.

    No surprise. #0 as immediate source value uses the constant generator, which is, surprise, R3 in register mode. So #0 and R3 are equivalent.

    old_cow_yellow said:
    Try MOV.B 0x3FFE(R8),R3; This one takes a lot longer to do nothing ;)

    How much is a lot? Just the time needed to read the 0x3FFE parameter? Or does it take forever (so 0x3FFE isn't read/skipped as source offset to R8)?

    Michal H. Tyc said:
    It looks like using R3 as destination results in interpreting the instruction as single-word,

    THis would surprise me a bit, since it would violate orthogonality at a much earlier stage than required. But of course possible.

    Michal H. Tyc said:
    It might be a trick for code obfuscation and making it harder to single-step with a debugger ;-) I have seen similar tricks in 6502

    I remember this very well from my good old C64. Also, the 6502 did have a lot of undocumented opcodes (like fusing INCX and CMPX into one instruction, saving one byte and one clock cycle). However, when the 65SC816 was introduced (the 16 bit 8/16MHz verison) and used in some speedup hardware, all these program failed to work.

  • Jens-Michael Gross said:
    What does the simulator say about R3 content?

    The Register window in IAR does not show R3 at all.

    Jens-Michael Gross said:
    THis would surprise me a bit, since it would violate orthogonality at a much earlier stage than required. But of course possible.

    The instructions with R2 and R3 as constant generators violate orthogonality anyway -- the addressing mode bits are (in a smart way) abused. Maybe R3 as destination accidentally influences source addressing mode, so PC is not incremented correctly (the source address word not read/skipped)? BTW, there is the CPU4 silicon bug related to the CG mechanism: CPU4 (PUSH #4, PUSH #8 not accessible with "short" opcodes using CG).

    Some further experiments:

    MOV.B 0x430E(R12), R3; clears R14, 0x430E is CLR.W R14 opcode, the line executed in 2 clks as NOP + CLR Rn
    MOV.W &0x430C, R3;     clears R12, as above

    I think I missed this effect earlier with MOV &TA0IV, R3 because this reads as MOV &0x012E, R3 and 0x012E is an undefined opcode which may be, by chance, silently ignored.

  • Michal H. Tyc said:
    The instructions with R2 and R3 as constant generators violate orthogonality anyway -- the addressing mode bits are (in a smart way) abused.

    You're right - for the source addressing modes. However, the source parameter in the example codes is a valid one and I would expect that the source operand is properly fetched before the (invalid) destination operand causes the process to stop. But little do I knwo about the internal structure of the MSP code. This discussion has shed some light on a few internals. And I'm surprised from (and not happy about) what I see.

    Michal H. Tyc said:
    0x012E is an undefined opcode which may be, by chance, silently ignored.

    Maybe. Or do unexpected things. However, on X or X2 core there are almost no undefined opcodes left (only 1XCX and 138x are still undefined). All formerly free opcodes are now either extension word, or A instructions or the extended pushm/popm and shift operations.
    0x012E is a MOVA &0x1xxxx, R14 instruction. (the following word is the remaining part of the 20 bit source address). Sicne it is a two-word isntruction, the processor will probably continue to execute bogus code until it finally slips back into the track (and may have already missed a jump)

  • Jens-Michael Gross said:
    But little do I knwo about the internal structure of the MSP code. This discussion has shed some light on a few internals. And I'm surprised from (and not happy about) what I see.

    Without knowing the internals, one can only guess. Maybe just saving some transistors was more important than precise dealing with a few rather deservedly undefined opcodes. The "more expected" behavior would be certainly also more elegant and consistent, and could even find an application, as we could see.

    Anyway, as long as this is documented as undefined, and the assembler (at least IAR) issues a warning, and nothing really bad seems to happen (as CPU lock-up or so), there is nothing to officially complain about...

    Jens-Michael Gross said:
    However, on X or X2 core there are almost no undefined opcodes left (only 1XCX and 138x are still undefined).

    It might be interesting whether CPUX and CPUXv2 also behave in the way described here. I do not have any to check, and the MSP430F449 from the original post also has the "classic" 16-bit core.

  • Michal H. Tyc said:
    It might be interesting whether CPUX and CPUXv2 also behave in the way described here. I do not have any to check, and the MSP430F449 from the original post also has the "classic" 16-bit core.

    I do have more than one, but I only have a workign development environment at work, where I don't have the time for experiments. And while I have some EXP boards at home, I never found the time yet to install the environment. (When I return from work, I don't have the nerves to do any private software or hardware projects).

    Well, now I have much more spare time, since my 'better half' left me after 16 years. But I don't know when I will be at the point where I start doing private hardware/software projects again.

  • Jens-Michael Gross said:
    And while I have some EXP boards at home, I never found the time yet to install the environment. (When I return from work, I don't have the nerves to do any private software or hardware projects).

    I understand very well. Anyway, I was just curious. I did not do anything serious with MSP430 so far (I work mostly with C2000 family, beside legacy LPC21xx-based projects and lots of PC stuff). I just have an MSP-EXP430G2 Launchpad for fun and very little time for it.

    Jens-Michael Gross said:
    Well, now I have much more spare time, since my 'better half' left me after 16 years.

    Sad, but it happens... Take care!

  • Michal H. Tyc said:
    I did not do anything serious with MSP430 so far

    Well, I dit enough for both of us :) but all were projects in my job, nothing private.

    The first project I want to do when I ever start with private projects, is a POV display for my bicycle. I've seen it somewhere and wanted to do a version with multiple colors and higher resolution.
    Well, it's more likely that I will finish my MSP book first :)

    Michal H. Tyc said:
    Sad, but it happens...

    Well, if you can't change it, accept it. I think I'm through with it  after 9 weeks now - until it comes back and hits me when I no longer expect it. If I could only load an old savegame to get the years back :) (but then, I'd have to write those 12k posts in this forum again)

  • Jens-Michael Gross said:
    Well, it's more likely that I will finish my MSP book first :)

    Great idea -- with you experience, MSP430 users would benefit a lot! And you could stop writing answers here for the same questions again and again, just point to the answer ;-)

    However, those who do not bother reading manuals and datasheets might not bother looking into your book, either...

  • Michal H. Tyc said:
    you could stop writing answers here for the same questions again and again, just point to the answer ;-)

    That was the intention (well, not the only one). However, looking up the right subchapter in the book to reference it, might take as long as writing the answer from scratch :)
    There's already an answer for most problems her ein the forum. But searching for it takes an eternity :)

    Michal H. Tyc said:
    However, those who do not bother reading manuals and datasheets might not bother looking into your book, either...

    Especially if I charge a cent or two :) I guess my dad will disinherit me when I let pass another opportunity to gain some money from my experience. It's already too much for him that I write here for free (well, I got some presents and awards and even a voyage to Texas from TI, but it doesn't come near a solid compensation for all the time I spent in the forum). And I guess my (ex-) girlfriend was thinking into the same direction too.

  • Jens-Michael Gross said:
    Especially if I charge a cent or two :)

    At least they might appreciate the amount of work and experience needed to write the book (and the forum anwers) then.

    Jens-Michael Gross said:
    It's already too much for him that I write here for free

    I hope that not being a 100% Homo oeconomicus does not mean not being a 100% Homo ;-)

     

  • Michal H. Tyc said:
    I hope that not being a 100% Homo oeconomicus does not mean not being a 100% Homo ;-)

    While there have been some speculations about me being a cloned AI, I'm definitely a homo sapiens sapiens, even though indeed no homo oeconomicus (at least money-related; regarding use of system resources, I am).

    However, my first thought about your sentence was "I'm definitely 0% homo" (and I really mean 0.00%). Because, at least in Germany, 'homo' is not a short for 'homo sapiens sapiens', but rather for 'homosexual person' (a typical case of 'false friends'). Even though I'm a big fan of Freddie Mercury.

  • Jens-Michael Gross said:
    ... I'm definitely a homo sapiens sapiens, even though indeed no homo oeconomicus (at least money-related; regarding use of system resources, I am). ...

    For that reason, I am not sure if you are a member of "behaviorally modern humans" ;)

  • Jens-Michael Gross said:
    Because, at least in Germany, 'homo' is not a short for 'homo sapiens sapiens', but rather for 'homosexual person' (a typical case of 'false friends').

    Well, it might be understood this way also here in Poland, I missed this. Maybe I quit my academic career too early to use Latin in a proper way ;-)

  • Michal H. Tyc said:

    ...  it might be understood this way also here in Poland, ...

    Michal,

    Off the topic just a bit. Did not know you are in Poland. I live in California and came here (via Berlin). Visited Warsaw last week. I am in Krakow this week. First time in this part of the world. 

    -- Lichen Wang (aka OCY)

  • old_cow_yellow said:
    I live in California and came here (via Berlin).

    You visited Berlin and didn't say hello to me? :(

  • old_cow_yellow said:
    Visited Warsaw last week. I am in Krakow this week.

    And I visited Warsaw last Monday, too... Are you going to visit some other places in Poland? Maybe Wroclaw (my city)?

    old_cow_yellow said:
    First time in this part of the world.

    I hope you have a nice time.

    Michal

  • Michal, I am having a great time. Unfortunately, we are not going to visit Wroclaw. We are going to Prague next.

    JMG, I have the impression that you are in Frankfurt. True? BTW, we took a train from Berlin to Warsaw and passed another "Frankfurt". Got me confused for a short while.

  • old_cow_yellow said:
    JMG, I have the impression that you are in Frankfurt. True?

    You apparently didn't read the social blog posts about me, here at e2e. (well, few people read the social blogs, I fear) No, I'm born, raised and employed in Berlin. And I mean the German capital, not the other Berlin (a village near Bad Segeberg).

    old_cow_yellow said:
    we took a train from Berlin to Warsaw and passed another "Frankfurt". Got me confused for a short while.

    Yes, we have a song here in Germany, where one verse reads "since Frankfurt is so big, it is divided in Frankfurt at the Oder and Frankfurt at the Main". Of course they are two independent metropolises.
    The reason is in the name itself. "Frankfurt" actually means "ford (Furt) of the Franks". Both independently founded at fords over a big river and then grown to big cities due to the trade routes. Frankfurt am Main is still a trade center, but the goods traded there today are money and company shares.

  • old_cow_yellow said:
    I am having a great time.

    And you still have time to write posts here? :-)

    old_cow_yellow said:
    Unfortunately, we are not going to visit Wroclaw. We are going to Prague next.

    Funny, I will attend a conference in Prague on the next Thursday.

**Attention** This is a public forum