Hi everyone. Old post, but interesting, and new information!
As you can see the RENDERER_WIDTH constant appears twice. And that's not good... At least I don't like it very much. So, my question is, how do you share constants between C and ASM code? Is there any "best practice" here?
Good question tulinmola, thanks for asking!
I am also very sensitive to the DRY principle (don't repeat yourself), SSOF (sigle source of truth) etc.
I see two uses for this:
* sharing memory addresses between asm and C, used to pass data. This is already well taken care of by Assembler and linker (declare extern on one side, declare global with value on the other). But it's not memory addresses that we want: we want constants.
* constants that can be used both sides to generate compact fast code, no indirections.
There are extra questions, like: ASM only knows integer values, but C can use #define (basically text) but also typed values (signed/unsigned integers, pointer), etc. Could we share values and get them typed on the C side?
To make you feel better (or not), I stumbled upon this problem two years ago and have not found a proper solution yet. Depending on the context, you may design your own workarounds. For instance, you may create a macro that generates both a #define and a piece of assembly. Something like this (warning: untested)
#define DEFINECONSTANT(C,VAL) \
#define C VAL \
void dummyfunction_##C##_VAL() __naked { \
__asm { \
.equ C, VAL \
}__endasm; \
}
It is the best I can think of by now.
Unfortunatey, by design preprocessor macros cannot generate
#define directives. This is similar to question
https://stackoverflow.com/questions/860273/macro-producing-macros-in-c , answer there is negative.
Yet there is hope!I've been facing the problem in a small project I'm doing (small path towards a greater goal) and think I may have found a solution that looks neat. It should allow to:
(1) define named constants,
(2) use them as compile-time constants in ASM as well as in C,
(3) allow to define some in reference to others if needed,
(4) allow to use them as parameters to macro calls (both assembly macros and C macros)
(5) if at all useful, also be available as typed (well, only one type, unsigned 16bit, but thats what they are anyway). -- I suspect the compiler will always to a better optimization with good old #defined values than with typed values anyway.
I'll tell how it goes.