I'm writing a bit of code for the MSP430F5438 that's trying to validate a string. I have my function validate_comms_msg(), which calls sprintf() to generate a string with a checksum that I then compare with the checksum included in the message to validate the message. Fairly straight forward.
My problem is returning from my validate_comms_msg() function. Somehow, when I return from my function, my program counter is going to the wrong place.
I've been pouring through the disassembly of my code for the past 4 hours, because I couldn't believe that this was happening. I've finally almost tracked down WHERE it's happening, but I still don't understand why.
validate_comms_msg() calls, towards the end of the function, sprintf().
C Code:
char calcChecksum[2];
sprintf(calcChecksum, "%X", CalcUARTChecksum(Message, Length));
Assembly:
0x07F32: 411C 0006 MOV.W 0x0006(SP),R12
0x07F36: 411D 000A MOV.W 0x000a(SP),R13
0x07F3A: 13B0 8F54 CALLA #CalcUARTChecksum
0x07F3E: 40B1 99C8 0000 MOV.W #0x99c8,0x0000(SP)
0x07F44: 4C81 0002 MOV.W R12,0x0002(SP)
0x07F48: 01CC MOVA SP,R12
0x07F4A: 503C 0010 ADD.W #0x0010,R12
0x07F4E: 13B0 9694 CALLA #sprintf
This isn't the only time that it calls it, and in the previous instances, it appears to work fine. However, for whatever reason, and I'm still not sure what that is, in this case, it doesn't quite work right.
Towards the end of sprintf(), somehow there's a call that is overwriting the location on the stack that contains my return address. Until this call, my return address is 0x007660, which is correct. However, when this assembly is called, my return address is changed to 0x007600, which is the wrong location, putting me almost at the beginning of my main().
0x096BC: 13B0 744C CALLA #_printfi
0x096C0: 411F 0006 MOV.W 0x0006(SP),R15
0x096C4: 43CF 0000 CLR.B 0x0000(R15) <- Problem happening here
0x096C8: 5231 ADD.W #8,SP
0x096CA: 0110 RETA
As far as I can tell, something is happening to the stack during the call to _printfi that puts the address of the return address onto the stack at SP+6, which then is loaded into R15, and cleared via the CLR.B instruction. However, I have no clue WHY this is happening, nor what to do about it.
What's the best way to figure out why this is happening? And specifically why it's happening this time, but not (as far as I can see) any other time? Is there any good way to wade through the _printf() disassembly? Or has anyone experienced this before, and have a fix for it? Is there another string handling routine I can use instead of sprintf? I'm just calling the version included in stdio.h, which is the version that's included in the CCS include directory.
For references, I'm using CCS 4.2.3.00004 with the MSP430F5438. I'll be happy to provide any other information, or snippets of code, memory dumps or any other information that might be needed to help figure out what's going on here.
Thanks,
Ian