Hi,
I'm interested in (re)writing a bunch of drivers for a project in
assembly, which will be called from C routines. The Compiler and
Assembler are GNU gcc and as.
I plan to run the Assembly language files through the C pre-processor
before actual assembly, so that a single header file can be shared
between the assembly driver routines and the C interface to the routine.
However, I'm having a problem trying to find a good and clean approach
for dealing with enums. Is there a way to define enums such that they
can be referenced correctly in both Assembly and C, without duplicating
it manually like in the following code fragment.
No, there's no better way than that. enums are a C language construct,
so they cannot be handled by an assembler.
I hacked a short Perl script that can automatically extract all enum
values from the stabs debugging information (-gstabs) of your object
file(s) (including the final ELF file), and return it as a sequence
of #define statements. So you could use that to construct an
assembler-only include file supplying #define macros that match the
C file's enum values.
Depending on your target CPU .equ's syntax may differ, refer to the gas
manual. Also you might want to use .equiv instead of .equ, again, refer
to the gas manual.
Thanks for all the suggestions. I prefer Bartli's approach since it's
done in a single pass. I suppose having to manually specify the enum
value each time is a minor tradeoff.
You have to be careful though to not specify two names for the
same value. This is perfectly legal for a C enum, but probably
rather not what you intend.
Yes...on second thought I'd think twice before using my approach because
it leaves you no choice but to assign every value manually.
Personally before I go and parse debug information to generate code I'd
probably rather invent an own small DSL (using an existing scripting
language, of course) and use that to define my data and have the C
headers and the assembly source generated from it.
This is fun. Here's a version that doesn't require you to assign the
values manually. You could easily extend this to provide full C enum
support where the values optionally may be assigned.
I've combined the two versions (to include assignment of values to
enums), and renamed BEGIN_ENUM/END_ENUM to ENUM_BEGIN/ENUM_END for
aesthetic reasons. In addition, I've put the macro definition outside of
the #define ENUM_BEGIN since I'm not sure what happens if multiple
ENUM_BEGINs are used (where the macro definition would be repeated).
Posted here for easy 'cut-n-paste'
Cool. I actually didn't know you could use semicolons as line breaking
character in gas, that's why I introduced the gas macro enum_value in
the first place.
Bartli wrote:
> Cool. I actually didn't know you could use semicolons as line breaking> character in gas, ...
It's processor-dependent. IIRC, the AVR uses semicolons as a comment
delimiter, and then offers dollar signs as alternate line breaking
characters instead.