The simplest way to is compile the C code to object files (gcc -c
to get some *.o
files) and then link them directly with the linker (ld
). You will have to link your object files with a few extra object files such as /usr/lib/crt1.o
in order to get a working executable (between the entry point, as seen by the kernel, and the main()
function, there is a bit of work to do). To know what to link with, try linking with the glibc, using gcc -v
: this should show you what normally comes into the executable.
You will find that gcc generates code which may have some dependencies to a few hidden functions. Most of them are in libgcc.a
. There may also be hidden calls to memcpy()
, memmove()
, memset()
and memcmp()
, which are in the libc, so you may have to provide your own versions (which is not hard, at least as long as you are not too picky about performance).
Things might get clearer at times if you look at the produced assembly (use the -S
flag).