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.

Detecting if compiler uses CALLA vs CALL instruction

I am optimizing some code and I want to have a C function call an ASM function. (no problem here). Problem is that depending on compilation settings, the ASM function will be called using either a CALL instruction or CALLA. Is there any way to detect this at compile-time in a header file or similar so that the ASM function can have a matching RET or RETA instruction. Any mismatch would surely blow up the stack. I would like to make the code as portable as possible and work for any device.

The MSP430X devices have #defines in the header such as __MSP430_HAS_MSP430XV2_CPU__ which indicate the extended instruction set. Unfortunately this does not necessarily mean that a CALLA will be used at compile time since the user could override the compiler to only use 16-bit calls.

Any ideas?

  • You're right, the user can override this (e.g. by chosing a different than the default memory model in the project settings). I'm not sure whether the compiler also generates a auto-define for the used memory model too.

    IIRC, the compiler will store information about which model used in the object file. So teh linker should be able to detect whether all modules have been compiled wiht the same model settings. At least for libraries, this works. There are different versions of each library depending on the model the code was compiled for.

    At runtime, there is no way to determine whether RET or RETA needs to be used. Of course, if the own functions address ins above 0x10000, then RETA is definitely required. Also, if the word below the return address is > 0x000f, then it cannot belong to the return address and therefore RET must be used. But there are still enough situations where you cannot be sure.

    At compile time, there is still teh uncertaint whether the caller and callee have been compiled with the same settings. If you change the model, it is possible that somefiles are not recompiled (since you didn't touc the source file) and still belong to the old setting. So even if you can determine teh memory model of teh calle at compile time, you cannot be sure which memory model was used for the caller. As I said, libraries have a flag (but maybe it's the responsibility of the library creator to properly set it). I have no idea whether there is a built-in machanism for plain object files. And in any case, you cannotbe sure by the compilation run alone.

**Attention** This is a public forum