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.

Mixing ASM and C

Other Parts Discussed in Thread: MSP430F2370

Hi,

I've read through the app note SLAA140 a few times regarding mixing ASM and C in a MSP430 design. In a current design, I've implemented a subroutine in ASM and followed the instructions to PUSH/POP all of the used registers (I am actually using R4-R11 !) upon entering and exiting the routine. I am concerned, however, that I am still missing a step as the subroutine seems to sometimes cause the MSP430 to reset. I've narrowed the cause down to this routine by commenting out the code during debugging. Note that when I am running this subroutine, I also have interrupts disabled, mainly to prevent a stack explosion.  

Any suggestions for things to review would be appreciated. 

Regards,

Chris

  • Hi Chris,

    I see that SLAA140 has not been updated since 2002, and things have changed in two key ways since then - the compilers have changed, and we now have the MSP430X cores, with 20 bit registers and addressing.

    The C calling convention changed in IAR 4, and it is also different if you are other compilers, like CCE/CCS or GCC. A document from 2002 will not reflect this.  I should be able to find the correct calling convention for your compiler is its documentation.

    If you are using a device with an MSP430X core, and you are compiling to take advantage of this larger address space, you need to allow for this in your assembly language code. You may need to push and pop an entire 20 bit register in some cases, and you will need to use "reta" instead of "ret" to return. A nice thing with the MSP430X is you can push and pop blocks of registers with a single instruction - pushm or popm.

     

  • I am using CCE and the target device is an MSP430f2370, not a MSP430X device. 

    In the corresponding header file, I have the ASM routine defined with an extern in front of it. I should have probably mentioned that the routine passes two parameters - a pointer to unsigned char and an array[8] of unsigned chars. The ASM code is getting called properly and executes as expected. However, i suspect that I am missing something in the ASM code to prevent erstwhile crashing. 

     

     

     

  • I'd say without yor assembly code posted here, there's nothing we can do for you except the general hints you already got.

    That your ASM code is properly called does only mean that your ASM code is formally correct and embedded properly into the project. I doubt it executes as expected, as I don't think you expect it crashing the system :) It does its calculations as expected would be a better description. What else it does (e.g. to the stack) is in the darkness of the undisclosed code.

    Looking into the .lst file at the point of the calling function might shed some light upon how the parameters are passed (which actually seems to work) and how the result is expected.

  • Jens-Michael,

    So true! Thanks for clarifying. 

    Basically, the routine in question is an adaption of the enc/dec algorithms described in this document. I adapted the code for CCE (it's targeted for IAR) and added a PUSH R4-R11 at the beginning and a pop R4-R11 at the end of the routine.  

    Thanks,

    Chris O'Malley

     

  • It seems obvious, but did you pop the registers in opposite order of pushing them? The POPM instruction in the 430X commandset takes care of this, but if you manually push/pop the individual registers using PUSH/POP...
    And do the pops/pushes match? (it's easy to skip one when you have such a large list).

  • Okay...it turns out I did have an issue in another part of the code and it is corrected now. But thanks all for your suggestions!

**Attention** This is a public forum