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.

TMS470PLF111 bricked processor code, what did I mess up in the assembly of this function?

I am trying to add an existing function call to old code, it was working then I changed the registers I was using to r0, maybe that is why? I also added NOP to replace a earlier line of code, NOP should 

be ignored and just carry on the to pop the registers and program counter off the stack and return? I also modified the data I was using OR on, so one of these 3 things caused it to brick it's self, not I need a new board. 

Here is the C code I am trying to write, by hand in hex. 

void FUN_00017600(){
byte *pbVar1;

pbVar1 = DAT_00017700;
DAT_00017700[0x35] = (*DAT_00017700 & 1) << 1 | DAT_00017700[0x35] & 0xfd; // the data in memory location at address  0x800 0C25 = ((data at location 8000bf0) & 1) << 1 | data at location 0x800 0C25 &0xfd
pbVar1[0x31] = pbVar1[0x35] | 2; //data at location 0x8000 C21 = data at location 0x8000 C21 | 0x2
return 0;
}

I see I messed this up should have been 31 not 35, but that shouldn't brick it? 

And here is a disassembly of the bad code:

 

                             *************************************************************

                             *                           FUNCTION                                     *

                             *************************************************************

                             undefined  FUN_00017600 ()

                               assume LRset = 0x0

                               assume TMode = 0x1

             undefined         r0:1           <RETURN>

                             FUN_00017600                                    XREF[1]:     FUN_0000fc3e:0000fd54 (c)  

        00017600 b5  9f           push       { r0, r1, r2, r3, r4, r7, lr }    ;maybe it is bad practice to use register r0?

        00017602 49  3f           ldr        r1,[DAT_00017700 ]                               = 08000BF0h

        00017604 4f  3e           ldr        r7,[DAT_00017700 ]                               = 08000BF0h

        00017606 37  30           adds       r7,#0x30

        00017608 e0  05           b          LAB_00017616

       

                             LAB_00017616                                    XREF[1]:     00017608 (j)  

        00017616 23  02           movs       r3,#0x2

        00017618 79  7a           ldrb       r2,[r7,#0x5 ]=>DAT_08000c25

        0001761a 43  9a           bics       r2,r3

        0001761c 78  09           ldrb       r1,[r1,#0x0 ]=>DAT_08000bf0

        0001761e 00  4b           lsls       r3,r1,#0x1

        00017620 21  02           movs       r1,#0x2

        00017622 40  19           ands       r1,r3

        00017624 43  11           orrs       r1,r2

        00017626 71  79           strb       r1,[r7,#0x5 ]=>DAT_08000c25

        00017628 37  01           adds       r7,#0x1

        0001762a 20  02           movs       r0,#0x2

        0001762c 79  39           ldrb       r1,[r7,#0x4 ]=>DAT_08000c25     ;should have been 0 

        0001762e 43  08           orrs       r0,r1

        00017630 70  38           strb       r0,[r7,#0x0 ]=>DAT_08000c21

        00017632 bf  00           nop                                                             ;NOP should be ok, should go on to return 

        00017634 bd  9f           pop        { r0, r1, r2, r3, r4, r7, pc }

 

                             DAT_00017700                                    XREF[2]:     FUN_00017600:00017602 (R) ,

                                                                                          FUN_00017600:00017604 (R)  

        00017700 08  00  0b  f0    undefine   08000BF0h                 ; 4 byte address to be loaded from memory 

  • Hi,

      I don't know your rationale behind writing assembly code. Why wouldn't you let the compiler take care of the code generation. I don't know what is wrong with your code and I can't support writing assembly. With the compiler optimization turned on, I can't image it produce bad and inefficient code compared to your writing a custom assembly code. If you must write in assembly, I will suggest you look at the disassembly output from the compiler and see what can still be improved.  

  • It is because it is rather difficult to take compiled code and insert it into existing compiled code, because all the addresses are off. Instead if I patch the instructions in with raw hex  I can control the memory addressing and jumps. I don't really want to work in C I prefer arm7. Is there a compiler that runs and tests arm7 code for tms470? 

    My question is can I use register r0 as a general purpose register or is that only for passing arguments to a function call?  

    Also can I use nop as a filler, that won't cause it to crash right?

    Otherwise then it must be crashing because I messed up my offsets and wrote to a area in ram that I wasn't expecting, and perhaps that is supposed to be used for other parts of the program, and it is being stuck in an infinite loop somewhere.   

  • I don't really understand what you are doing.  But I can comment on two details in the assembly code.

    I presume this function follows the same register conventions as all the Arm compilers supported by TI.  This means the registers r0-r3 do not need to be preserved.  It is up to the caller to preserve them, if needed (which I've never seen happen in practice).  Thus, you don't need to push/pop these registers.

    To ...

    return 0;

    ... you need to load the value 0 into r0 just before returning.  I don't see any instructions to do that.

    Thanks and regards,

    -George

  • Oh, ok thanks a lot for the tips, you rock! I am sorry I am very new to this and just a new student, learning!  

    Do I need to mov 0 into r0 even if I don't use r0, register? I don't think the existing code ever loads zero into r0,

    but maybe it never used r0 other than to pass arguments to another function. Perhaps that's why it bricked its self,

    what happens if you don't move 0 to r0? 

  • If none of the calls to the function use the return value, then it doesn't matter what is in r0.  But if just one call uses the return value, then r0 must be loaded with 0 just before the return.

    Thanks and regards,

    -George