Based on the files in your question, I managed to compile it. I've changed both the file names and the file contents.
asm_const.h :
#define ASM_CONST_1 0x80
#define ASM_CONST_2 0xaf
asm_functions.h :
#include "asm_const.h"
unsigned char asm_foo( int, int, int );
asm_functions.S (the trailing S must be capital! #include needs it) :
#include "asm_const.h"
.section .text
.globl asm_foo
.type asm_foo, @function
asm_foo:
mov ASM_CONST_1, %eax
/* asm code with proper stack manipulation for C calling conventions */
ret
test_asm.c :
#include "asm_functions.h"
int main() {
return asm_foo( 1, 2, 3);
}
Please note that you need the the assembly file extension .S with capital S. With .s, the .s file wouldn't be run through the preprocessor, thus #include wouldn't work, and you wouldn't be able to use ASM_CONST_1 in the .s file.
Compile with a single command:
gcc -o test_asm asm_functions.S test_asm.c
Or, as an alternative, compile with multiple commands, creating .o files:
gcc -c asm_functions.S
gcc -c test_asm.c
gcc -o test_asm asm_functions.o test_asm.o
The single-command gcc takes care of compiling the .S file using gas, the .c file with GCC's C compiler, and linking the resulting temporary .o files together using ld. gcc runs all those commands with the appropriate flags by default.
On some systems (but not on Linux with the default GCC installation) you have to prepend an underscore to the names of exported functions in the .S file (but not in the .c or .h files). So all instances of asm_foo
would become _asm_foo
only in the .S file.