This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Using conditionals within shared (C & ASM) header file

Last June, someone asked about how command line symbols defined for both the assembler and the C compiler could be referenced within a conditional (if) statement within a universal shared header file. A company rep said they'd forward this to the tech team for advice. Whatever happened?

The issue is this: Symbols of identical name specified on the command line for the assembler and the C compiler end up being unique symbols. Those specified for the assembler are defined as per a "$set" directive and are visible only to the assembler. Those specified for the C compiler are defined as per a "#define" directive and are only visible when running the compiler.

In other words, there is no way to define a symbol on the A51 assembler command line that will be visible to the C preprocessor within the assembler. Symbols defined this way are only visible to "$if" statements.

PROBLEM: A universal header file containing an "#ifdef SYMBOL" conditional branch will work within C modules, but will not work within assembler modules because the assembler's C preprocessor WILL NOT recognize the referenced symbol and will thus test false.

Example:

#ifdef SYMBOL
  #include <me.h>
#endif
will test as false within the assembler C macro preprocessor if SYMBOL is only defined on the command line. Of course, an explicit
#define SYMBOL
appearing before the conditional will force the condition to be TRUE, but that is not what we are trying to do here. We want the command line argument to trigger different code versions, for example, to target different hardware configurations.

So it's 2005. Any solutions to this dilemma yet?

Parents
  • The problem is not that the assembler won't recognize #define-type symbols --- it will do that just find. The problem used to be that you can set such macros in an assembler run from outside the source file. I.e. you could

    #define TURN_ON_OPTION_FOO 1
    in an assembly module just fine, but there was no command line switch to the same effect.

    Should be fixed by the addition of the DEFINE command line directive to Ax51 of C51 version 7.07.

Reply
  • The problem is not that the assembler won't recognize #define-type symbols --- it will do that just find. The problem used to be that you can set such macros in an assembler run from outside the source file. I.e. you could

    #define TURN_ON_OPTION_FOO 1
    in an assembly module just fine, but there was no command line switch to the same effect.

    Should be fixed by the addition of the DEFINE command line directive to Ax51 of C51 version 7.07.

Children
  • Kudos to Mr. Broeker! The DEFINE command line option is EXACTLY what we were looking for. And to think it has been there for all this time!

    It would appear that the online updates distributed by Keil in recent years/months do not always contain equally updated documentation. The DEFINE command line option is not mentioned in the PDF version of the Assembler User Guide that we have and, unfortunately, this feature had totally eluded us until this moment.

    Note to self: Regularly scan all Release Notes published by Keil on their website!

    Thank you again Mr. Broeker. Problem solved!

  • It would be nice if the assembler would accept any .h file. Often I have to make several to separate out what the assembler can not handle.

    Obviously it would not make much sense for the assembler to recognize a struct (converting all entries to offset, however could be usefun) but could it maybe just skip it instead of complaining?

    also extern array should not be a problem.

    Erik

  • I have to agree with others here that problems resulting from "bilingual" API/include files (fully compatible with the compiler or assembler) can be a real headache, and I'm sure we've all come up with our work-arounds.

    Keil likely has to prioritize its feature/fix tasks, but considering that the targets are relatively small controllers, assembly language requirements aren't uncommon. Given this, providing a robust common syntax between assembler and C would be a big benefit IMO.

    If it were me, I'd look at the header files in C format and ask, "how can we make the assembler understand as much of this as possible, if no all of it?"

    (my 2c)

  • If it were me, I'd look at the header files in C format and ask, "how can we make the assembler understand as much of this as possible, if no all of it?" - and ignore the rest

    (my 3c)

    Erik

  • Yes, that too.

    Frankly, I don't know why it couldn't index structures (somehow) as you suggested, resolve prototypes, and much more.

  • Frankly, I don't know why it couldn't index structures (somehow) as you suggested, resolve prototypes, and much more.

    Well, as it reached the "much more" part of that request, at the latest, it would be a mostly complete re-implementation of the existing C compiler. I hope you can agree that creating such a beast would be a waste of everyone's time and money.

    If you want to use all kinds of C constructs, A51 is not the place to go looking for them.

  • Often I have to make several to separate out what the assembler can not handle.

    Hmm... what's wrong with just putting a big

    #ifdef __C51__
    /* ... */
    #endif
    around those parts A51 can't understand? If you don't like the dependency on the vendor-specific macro __C51__, just use __STDC__ or any other macro name you like (and set up in the makefile or project C options, accordingly)

  • The funny thing about your suggestion is that one of the things the assembler can not handle is #ifdef.

    Erik

  • Actually it does. I already use that one.

  • Well, as it reached the "much more" part of that request, at the latest, it would be a mostly complete re-implementation of the existing C compiler. I hope you can agree that creating such a beast would be a waste of everyone's time and money.

    Actually, it would be a re-implementation of the A51 assembler...a likely far simpler interpreter than the compiler, in that its simply translator. As far as it being a waste of time or money, I dont know? Intel thought it important to include constructs such as structures into ASM-86.


    If you want to use all kinds of C constructs, A51 is not the place to go looking for them.

    Its my users that want C constructs in a libraries API. Said library I must code in assembly. The less cluttered the API file (i.e. more compatible with the A51 implementation), the more readable the user will find it to be.

  • that must be in a revison later than when I gave up on it. Not necessarily later than the one I use (7.xx).

    Erik

  • I can believe that because now that I think about it, I recall it failing in the past.

    Hmmmm, seems some C51 constructs are creeping into A51 after all ;)

  • In our shared headers we extensively use both

    #ifdef __C51__
      ... stuff intended only for C51 compiler
      ... such as structure definitions
    #endif
    and
    #ifndef __C51__
      ... stuff intended only for A51 Assembler
      ... such as assembler macros
    #endif
    Note also, if you didn't already see it, Mr. Broeker also pointed out, earlier in this thread, the existence of the DEFINE (or DF) command line option for the A51 Assembler. This allows you to send C-type symbols (equal to #define) to the Assembler's C macro translator, thus enabling conditional/alternate assembly paths within C-type header files.

  • Its my users that want C constructs in a libraries API. Said library I must code in assembly.

    What could be stopping you from implementing at least the bulk of it in C?

    Anyway: just because the API is compatible with C doesn't mean the assembler has to learn C, too. Only the assembly programmer has to --- and the C compiler will help him, if asked. That's what the SOURCE directive really is about: take C source code and produce (dummy) assembly code from it, so a human assembly programmer can work from that as a baseline.