3

I'm trying to compile assembly and C code together (not C to assembly), but can't get it done.

For example:

file common.h

#ifndef __COMMON_H__
#define __COMMON_H__

struct tree{
        tree* left;
        tree* right;

        void* elem;
};

void foo(int c);
#endif

file common.S

#include "common.h"

    .text
    .globl foo
    .ent foo
foo:
     //foo implementation

    .end foo

When I try to compile this:

# gcc -c common.S
common.h: Assembler messages:
common.h:5: Error: unrecognized opcode `struct tree{'
common.h:7: Error: unrecognized opcode `tree* left'
common.h:8: Error: unrecognized opcode `tree* right'
common.h:10: Error: unrecognized opcode `void* elem'
common.h:12: Error: junk at end of line, first unrecognized character is `}'
common.h:14: Error: unrecognized opcode `void foo(int c)'

Is there any way to take C-definitions into assembly using gcc?

halfer
  • 19,824
  • 17
  • 99
  • 186
Tom
  • 43,810
  • 29
  • 138
  • 169

4 Answers4

4

No, you can't include C declarations in assembly language. The assembler has no idea what struct tree means.

If you want to write an assembly language function foo that makes use of your definition of struct tree, you're going to have to do it without making use of the C header file.

To get an idea of what this might look like, write the foo function in C, compile it with gcc -S to generate an assembly listing, and then take a look at the resulting compiler-generated common.s file. (You should probably do this in a separate directory so you don't clobber your existing common.s file.)

You probably won't see any references to struct tree or to the member names left, right, and elem; instead, you'll see assembly opcodes that refer to data at certain offsets.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

The C preprocess is just text substitution / file inclusion, and struct tree{ ... }; isn't valid GAS syntax.


If you have headers that have some #define constants useful for asm, you can put those parts inside #ifdef __ASSEMBLER__.

Or put the non-assembler-compatible parts in #ifndef __ASSEMBLER__ blocks.

Or separate the asm-compatible parts into a .h file that asm can include. The Linux kernel does this with a few things like #include <asm/unistd.h>. (But there are other constants that don't have asm-friendly headers, so preprocessing them with gcc -E -dM to dump just the macro defines can be useful if you have some existing .h headers with mixes of #define macros and C syntax.)


When preprocessing a .S file, GCC pre-defines __ASSEMBLER__ for you. You could make up your own macro name yourself and have your Makefile use gcc -DASM_ONLY to build .S files, but __ASSEMBLER__ is a pretty clear and good choice of name.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
1

You don't need to compile the header file. Try this:

# gcc -c common.S

without

#include <common.h> 

in common.S

Anthony Blake
  • 5,328
  • 2
  • 25
  • 24
  • Im not sure that's an option. The idea to include the `#include` in the .S is not mine. Im reading OS code in the `arch/` section, and in there it includes the .h files. – Tom Nov 24 '11 at 02:32
  • Ahh OK.. leave the include and compile it without the header then -- you don't need to compile the header if its included. – Anthony Blake Nov 24 '11 at 02:36
  • `# gcc -c common.S ` same output :( – Tom Nov 24 '11 at 04:05
0

I recommend you review Inline Assembler Cookbook.

Jeff
  • 1,364
  • 1
  • 8
  • 17