18 Jun 2012
NOTE (2016-11-01)
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 towhatever.o
as you normally would (usinggcc
, notas
).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:
myAsmFile.asm
#include <header.h> mov eax, EXACT_PI
include/header.h
#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.