How to use assembler (as) in UNIX? [I got errors using assembler]

Hi, folks,

I have a simple program main.c. The program is very simple, just for testing purpose. The program was proven correct by using "gcc".

Now I would compile it step by step from main.c to main.o. Here is what I did:

cpp main.c main.i <This step succeeded>
cc main.i -o main.s <This step also succeeded>
as -o main.o main.s
<OOPS :frowning: , I got a huge list of errors at this step. Most of them are like
"main.s Error: junk at end of line, first unrecognized character valued 0x..."
or "main.s:1: Error: invalid character (0x1) in mnemonic"

Anybody has a clue what's happening here? Thank you!

cc main.i -o main.s <This step also succeeded>

Maybe, but main.s is probably an executable type of file despite the name. Look at it with an editer. You need some flag to tell the compiler to stop after generating assembler.

Aha, I tried with cc -S main.i main.s
Now the main.s contains assemble instructions.

But after as -o main.o main.s

I use ld to link it: ld -o main main.o
the system reports:
$ ld -o main main.o
ld: warning: cannot find entry symbol _mainCRTStartup; defaulting to 00401000
main.o(.text+0x15):main.c: undefined reference to `_alloca'
main.o(.text+0x1a):main.c: undefined reference to `__main'
main.o(.text+0x26):main.c: undefined reference to `malloc'
main.o(.text+0x5d):main.c: undefined reference to `printf'

That's wierd. Any clue?

You are making a lot of extra work for yourself, you should just let the compiler do the work. You don't say what OS you are using, etc. But in general. when cc invokes ld it tends to do two more things...
1) it includes some some stub to call main... this is often called crt0.o or something like that.
2) it includes some standard libraries

This sounds like a link library issue, as a result of troubled gcc installation on cygwin.
_alloca is defined in libgcc.a.
__main is defined in libc.a

So, to solve these linker errors, you would need to explicity specify the link libraries such as libgcc.a and libc.a

This is how you do it :
In your makefile define variable LIBS and LIBDIR. Set the LIBDIR to point to where the library files are.

LIBS = $(LIBDIR)/libgcc.a $(LIBDIR)/libstdc++.a /lib/libc.a

Now include the $(LIBS) in the linker command.

$(PROJECT).bin: $(OBJECTS)
$(LD) -M -nostartfiles -nodefaultlibs -T $(LINK_FILE) -o \
$(PROJECT).bin $(OBJECTS) $(LIBS) > $(PROJECT).map

This should resolve the issue.

If you are really interested in knowing howto use the assembler on UNIX you should write a small piece of code in assembly instead of in C. What you are doing essentially is breaking down the steps taken by the compiler to produce object code. The C source code is first translated into assembly by the compiler. The assembly listing is then translated down into object code by the assembler. cc is much like a wrapper that bundles both the C compiler [on AIX it's called ccom] and the assembler [as] into one software package.