Reputation: 520
I have written a Hello World program in C. I used the command gcc -S -o hello.s hello.c
(code was in hello.c) to generate assembly, then used as
to assemble it. Finally I linked the object code using ld
, but it gave me the following error:
ld: a.out:hello.c:(.text+0xa): undefined reference to `__main'
ld: a.out:hello.c:(.text+0x16): undefined reference to `puts'
The C code was as follows:
#include <stdio.h>
int main(void) {
printf("Hello world!\n");
}
I use an Intel Core i3 processor, and used MinGW to compile. My operating system is Windows 7.
This was the generated assembly:
.file "hello.c"
.text
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "Hello world!\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB13:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movl $LC0, (%esp)
call _puts
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE13:
.ident "GCC: (MinGW.org GCC Build-2) 9.2.0"
.def _puts; .scl 2; .type 32; .endef
Upvotes: 2
Views: 762
Reputation: 735
These are the steps I generally follow for the manual Build process with either gcc (C) or g++ (C and C):
gcc -E file.c -o file.i
gcc -S file.i -o file.s
gcc -c file.s -o file.o
gcc file.o -o file.out
The the 1st step (Preprocessing) can also be performed with cpp file.c > file.i.
In the 2nd step (Compiling) I sometimes also name the assembly file as .asm instead of .s. .s
is traditional for Unix assembler source files, while .asm
is traditional for assemblers like NASM. .S
source files will get preprocessed and assembled.
In the 3rd step (Assembling) you can also use the assembler directly: as file.s -o file.o. If you used gcc -v -c file.s
(verbose), you'd see it was just running as
on it.
In the 4th step (Linking) you could also use the ld tool directly, but the right options for paths and libraries depends on the system so it's normally best to let GCC invoke ld
for you. With gcc -v
, it will show you what options it passed.
Finally, if we have a very simple application where we don't need a tool like Cmake or Bazel, then we can resume the above steps in a single command: gcc file.c -o file.out.
Again, gcc -v
will show you the commands it ran to carry out the internal steps, from whatever starting point to wherever you told it to stop. (With the default being to make an executable.)
Upvotes: 2
Reputation: 520
Thanks to Nate Eldredge for helping me get the answer.
To link the file produced by as
, use gcc -v (file)
.
Upvotes: 1