Polygot include file for nasm/yasm and C - c

I have a bunch of magic numbers that I would like to include in both a C program and an assembly file to be compiled by nasm or yasm.
In plain C the file would look something a series of defines, like:
#define BLESS 55378008
#define ANSWER 42
...
In nasm or yasm, the same include could be implemented as:
%define BLESS 55378008
%define ANSWER 42
...
The only difference is that leading character before the define: # for C and % for nasm.
Is there any way to write a polygot include that allows me to include it in both C and nasm and only list the constants once?
Yes, I'm aware that I could just use sed or whatever to generate one file from the other.

NASM by itself has no way to include C header files in assembly code. This has been brought up in the NASM forum through the years. You will need an external tool to parse the C header files into something usable with NASM assembly syntax.
One such 3rd party contribution that is suppose to be compatible with NASM is h2incn. I haven't tested it thoroughly enough so can't say it is stable or usable enough for all use cases.
The alternative is to pre-process the files with other tools like m4, cpp, or even translating with sed

Related

Unable to include ASM header file in C without losing preprocessor

Short version:
I want to be able to define assembler macros in a macros.S and use them from inside asm() statements in GNU C.
I can do this with asm(".include \"macros.S\""); near the top of my C source, but I want macros.S to go through the C preprocessor.
Long version:
In GCC asm, *.S files are preprocessed by the C preprocessor, allowing use of C style #define, etc.
In GCC C, you can include an asm header file (which may include asm macro definitions, .set declarations, etc), by writing asm(".include \"myasmheader.S\""); near the top of a file.
Including an ASM header file in this manner allows you to use asm macros inside asm blocks.
Unfortunately, doing so does not invoke the C preprocessor on the .S file being included (as the .include is done later in the compilation process), and so #defines are no longer substituted.
So is there any way to properly include a .S file inside of a C file?
Some other compilers support:
#asm
#include "myasmheader.S"
#endasm
Which would not exhibit such a problem. But alas, GCC seems to require that all asm inside of a C file is in the form of strings.
Short of not using asm (not an option, embedded DSP project that heavily mixes asm and c), or removing use of the C preprocessor in ASM files, what can be done?
From the comments:
Add preprocessing of the ASM file (via cpp) as a distinct build step into whatever build system you're using.
Credits to arrowd and Ped7g.

Can you add preprocessor directives in assembly?

I would like to execute some assembly instructions based on a define from a header file.
Let's say in test.h I have #define DEBUG.
In test.asm I want to check somehow like #ifdef DEBUG do something...
Is such thing possible? I was not able to find something helpful in the similar questions or online.
Yes, you can run the C preprocessor on your asm file. Depends on your build environment how to do this. gcc, for example, automatically runs it for files with extension .S (capital). Note that whatever you include, should be asm compatible. It is common practice to conditionally include part of the header, using #ifndef ASSEMBLY or similar constructs, so you can have C and ASM parts in the same header.
The C preprocessor is just a program that inputs data (C source files), transforms it, and outputs data again (translation units).
You can run it manually like so:
gcc -E < input > output
which means you can run the C preprocessor over .txt files, or latex files, if you want to.
The difficult bit, of course, is how you integrate that in your build system. This very much depends on the build system you're using. If that involves makefiles, you create a target for your assembler file:
assembler_file: input_1 input_2
gcc -E < $^ > $#
and then you compile "assembler_file" in whatever way you normally compile it.
Sure but that is no longer assembly language, you would need to feed it through a C preprocessor that also knows that this is a hybrid C/asm file and does the c preprocessing part but doesnt try to compile, it then feeds to to the assembler or has its own assembler built in.
Possible, heavily depends on your toolchain (either supported or not) but IMO leaves a very bad taste, YMMV.

How to access C preprocessor constants in assembly?

If I define a constant in my C .h file:
#define constant 1
How do I access it in my assembly .s file?
If you use the GNU toolchain, gcc will by default run the preprocessor on files with the .S extension (uppercase 'S'). So you can use all cpp features in your assembly file.
There are some caveats:
there might be differences in the way the assembler and the preprocessor tokenize the input.
If you #include header files, they should only contain preprocessor directives, not C stuff like function prototypes.
You shouldn't use # comments, as they would be interpreted by the preprocessor.
Example:
File definitions.h
#define REGPARM 1
File asm.S
#include "definitions.h"
.text
.globl relocate
.align 16
.type relocate,#function
relocate:
#if !REGPARM
movl 4(%esp),%eax
#endif
subl %ecx,%ecx
...
Even if you don't use gcc, you might be able to use the same approach, as long as the syntax of your assembler is reasonably compatible with the C preprocessor (see caveats above). Most C compilers have an option to only preprocess the input file (e.g. -E in gcc) or you might have the preprocessor as a separate executable. You can probably include this preprocessing prior to assembly in your build tool.
You can't, unless a specific development chain allows it. But in 20 years or so of embedded programming I never saw one.
Usually, the only way for assembly and C to communicate is the linker, i.e. labels defined in C/C++ are accessable from within assembly (and vice versa).
When I had to share definitions between C/C++ and asm, I usually did it with a custom code generator.
Since high-level data are rarely exchanged with assembly, a few defines and maybe some external references are usually enough, and thus the code generator is really easy to make.
You can use for instance perl or awk to parse a very simple list of common constants and produce a pair of files, one with #defines and the other with the equivalent EQU directives.

How to compile assembly language in c

I am looking at lots of assembly language code that is compiled along with c. They are using simple #define assembly without any headers in boot.s code. How does this work ?
Typically .s files are processed by an assembler. Without knowing any other details, there's nothing more to say. .s file goes in, .o file comes out.
Many assemblers provide some kind of include directive to allow use of headers, which would also be in assembly language.
Ah, the code you linked is for use by the GNU as assembler. If you're on Linux or Mac, do man as to learn about it. If you're on Windows, install MinGW or Cygwin.
Compilers can frequently include in-line assembly, but I believe it is compiler specific.
I don't remember the precise details, but I think its something like:
void myFunc(void)
{
int myNum; /* plain old C */
__asm /* Assembly */
{
mov ax,bx;
xor cx,cx;
}
myNum = 5; /* more C */
}
Research your specific compiler for details.
The link you post in your comment is an assembly language source file that is meant to be first run through a c-preprocessor. It's just a programming convenience, but lots of assembly language compilers support similar constructs anyway, so I'm not sure why they went the c-preprocessor route.
If you have "main proc" inside of your code, you are using x86 architecture and your file ends with .asm you con use for compilation:
tasm fileName.asm
In result you will get your fileName.obj file. After that you need to link it and for
that you can use tlink filename.obj
To run, just enter the filename.exe on the command line
If you need to link more than one file use tlink filename1.obj filename2.obj and so on
during the compilation and linking is not necessary to specify the file extension like .obj or .asm. Using just filename should be fine.

Using the C Preprocessor for languages other than C

The Wikipedia entry for the C Preprocessor states:
The language of preprocessor
directives is agnostic to the grammar
of C, so the C preprocessor can also
be used independently to process other
types of files.
How can this be done? Any examples or techniques?
EDIT: Yes, I'm mostly interested in macro processing. Even though it's probably not advisable or maintainable it would still be useful to know what's possible.
You can call CPP directly:
cpp <file>
Rather than calling it through gcc:
gcc -E filename
Do note however that, as mentioned in the same Wikipedia article, C preprocessor's language is not really equipped for general-purpose use:
However, since the C preprocessor does not have features of some other
preprocessors, such as recursive macros, selective expansion according
to quoting, string evaluation in conditionals, and Turing
completeness, it is very limited in comparison to a more general macro
processor such as m4.
Have you considered dabbling with a more flexible macro processing language, like the aforementioned m4 for instance?
For example, Assembler. While many assemblers have their own way to #include headers and #define macros, it can be useful to use the C preprocessor for this. GNU make, for example, has implicit rules for turning *.S files into *.s files by running the preprocessor ('cpp'), before feeding the *.s file to the GNU assembler ('as').
Yes, it can be done by parsing your own language through the gcc preprocessor (e.g. 'gcc -E').
We have done this on my job with our our, specific language. It has quite some advantages:
You can use C's include statements (#include) which is very powerful
You can use your #ifdef constructions
You can define Constants (#define MAGIC_NUMBER 42) or macro functions (#define min(x,y) ( (x( < (y) ? (x) : (y))
... and the other things in the c processor.
HOWEVER, you also inherit the unsafe C constructions, and having a preprocessor not integrated with your main language is the cause of it. Think about the minimum macro and doing something like :
a = 2;
b = 3;
c = min(a--, b--);
Just think what value a and b will have after the min function?
Same is true about the non-typed constants that you introduce
See the Safer C book for details.
Many C compilers have a flag that tells them to only preprocess. With gcc it's the -E flag. eg:
$ gcc -E -
#define FOO foo
bar FOO baz
will output:
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
bar foo baz
With other C compilers you'll have to check the manuals to see how to swithc to preprocess-only mode.
Usually you can invoke the C compiler with an option to preprocess only (and ignore any #line statements). Take this as a simple example:
<?php
function foo()
{
#ifdef DEBUG
echo "Some debug info.";
#endif
echo "Foo!";
}
foo();
We define a PHP source file with preprocess statements. We can then preprocess it (gcc can do this, too):
cl -nologo -EP foo.php > foo2.php
Since DEBUG is not the defined the first echo is stripped. Plus here is that lines beginning with # are comments in PHP so you don't have to preprocess them for a "debug" build.
Edit: Since you asked about macros. This works fine too and could be used to generate boilerplate code etc.
Using Microsoft's compiler, I think (I just looked it up, haven't tested it) that it's the /P compiler option.
Other compilers presumably have similar options (or, for some compilers the preprocessor might actually be a different executable, which is usually run implicitly by the compiler but which you can also run explicitly separately).
Assuming you're using GCC, You can take any plain old text file, regardless of its contents, and run:
gcc -E filename
Any preprocessor directives in the file will be processed by the preprocessor and GCC will then exit.
The point is that it doesn't matter what the actual content of the text file is, since all the preprocessor cares about is its own directives.
I have heard of people using the C pre-processor on Ada code. Ada has no preprocessor, so you have to do something like that if you want to preprocess your code.
However, it was a concious design decision not to give it one, so doing this is very un-Ada. I wouldn't suggest anyone do this.
A while ago I did some work on a project that used imake for makefile generation. As I recall, it was basically the c preprocessor syntax to generate the make files.
The C preprocessor can also be invoked by the Glasgow Haskell Compiler (GHC) prior to compiling Haskell code, by passing the -cpp flag.
You could implement the C preprocessor in the compiler for another language.
You could use it to preprocess any sort of text file, but there's much better things for that purpose.
Basically what it's saying is that preprocessors have nothing to do with C syntax. They are basically simple parsers that follow a set of rules. So you could use preprocessors kind of like you'd use sed or awk for some silly tasks. Don't ask me why you'd ever want to do it though.
For example, on a text file:
#define pi 3.141
pi is not an irrational number.
Then you run the preprocessor & you'd get.
3.141 is not an irrational number.

Resources