18 Jun 2012
Since people are apparently still finding this page four years later (yay! Cool URLs don't change!): I've since found a better and more correct way of doing this.
If you're compiling using
gcc, you can just name your assembly files (with includes and macros and stuff)
whatever.S(capital S), and compile them right down to
whatever.oas you normally would (using
GNU make also has a builtin rule that does this automatically... yeah...
From this I've learned the following
- Trust make. It's terribly powerful if you trust it to be.
- GCC is not the GNU C Compiler. It's the GNU Compiler Collection.
Something that always annoyed me is how hard it is to synchronize constants between assembly and c code. In assembler, you define a constant value as
EXACT_PI equ 3
and in c
#define EXACT_PI 3
As is usually the case with things that annoy me, there is of course a solution to this, as I found out today. The solution is the c preprocessor.
Normally, when you run a c compiler, it makes multiple passes over your source file. The first one or two times, it runs a pre-processor. The preprocessor checks for things like #include and #define and replaces macros. The next pass actually compiles the code. Then the compiler invokes a linker and so on.
What I found out today is that you can run only the preprocessor and it will replace all the preprocessor code and ignore the rest. In other words, you can use c preprocessor macros in assembler. Awesome!
So, how is this done? Well, here's a minimal (non-working) example:
#include <header.h> mov eax, EXACT_PI
#pragma once #define EXACT_PI 3 #ifndef __ASSEMBLER__ // This is not evaluated if header.h is included from an assembly file. #endif
This is compiled through:
$ cpp -I include -x assembler-with-cpp myAsmFile.asm -o myAsmFile.s $ nasm myAsmFile.s
The -x-flag tells the preprocessor what type of file the following input files are. assembler-with-cpp means cpp will ignore everything but the preprocessor commands.
An alternative to cpp is gcc -E. Actually, this is often exactly the same thing...
This is implemented in git commit 742f2348ec.