Question

I've got a problem with my program. When I'm trying to compile my C program with assembly function using this line:

gcc -o program factarial.c

I get this and I don't know why:

/tmp/ccFKqbDP.o: In function `main':
factarial.c:(.text+0x11): undefined reference to `factarial_asm'
collect2: ld returned 1 exit status

This is my C code:

#include <stdio.h>

extern void factarial_asm();

int main ()
{
 factarial_asm (5);
 return 0;
}

And this is assembly code:

.data
.text
.global _main
.type factarial_asm, @function

factarial_asm:
    pushl %ebp
    movl %esp, %ebp
    movl 8(%ebp), %eax
    cmpl $1, %eax
je koniec
    decl %eax
    pushl %eax
call factarial_asm
    movl 8(%ebp), %ebx
    mull %ebx
koniec:
leave
ret

Also, when I'm trying to compile asm code with C function using this line:

gcc -o program factarial.s

I get this problem:

/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
/tmp/ccWCmTBe.o: In function `main':
(.text+0x3): undefined reference to `factarial'
collect2: ld returned 1 exit status

This is my asm code:

SYSEXIT = 1
EXIT_SUCC = 0
SYSWRITE = 4
SYSCALL = 0x80
SYSREAD = 3

.align 32
.text
.global _main
main:

pushl $5
call factarial

movl $SYSEXIT, %eax
movl $EXIT_SUCC, %ebx
int $SYSCALL

And my C code:

#include <stdio.h>

int factarial(int n)
{
    if(n == 0) return 1;
    else       return n * factarial(n - 1);
}

I know that it's so much questions, but so far I was preparing as compiler and ld linker so I don't exactly know how to use gcc. Also, could anyone help me with preparing makefile file?

Was it helpful?

Solution

The problem is each of your compilation lines are trying to create your executable without the full program. You somewhat complicate things if your source files are the same name with a different extension.

One simple option is instead, this command: gcc -o program factarial.c factarial.s.

Alternatively you might consider compiling but not linking your individual source files, and then linking their objects together to build your executable. Assuming your source files were named a.c and b.s, you would:

gcc -c a.c
gcc -c b.s
gcc -o program a.o b.o

Finally (and not related to your problem, of course), I believe the word you are looking for is factorial :)


There still exists a problem in your assembly. First, I've recreated your results, as seen here:

$ gcc -c factarial.c
$ gcc -c factarial_asm.s
$ gcc -o program factarial.o factarial_asm.o
factarial.o: In function `main':
factarial.c:(.text+0xf): undefined reference to `factarial_asm'
collect2: error: ld returned 1 exit status

Next, I used the nm command to inspect the object files:

$ nm factarial.o
                 U factarial_asm
0000000000000000 T main
$ nm factarial_asm.o
                 U _main
0000000000000000 t factarial_asm
000000000000001a t koniec

There are some interesting things in the nm output for the assembly object. First, U _main tells us that main() is undefined in that object, meaning it's expected to be found when we link the program. This file doesn't call main() so we really shouldn't even care about that. This is caused by .global _main, which can safely be removed.

Next, the symbol for factarial_asm is a lower case t, not the T found in main() from the primary C source... being shown as t means the symbol is local to that source file only, it's not exported to others. (In C, this is the difference between void function() {} and static void function() {}). We need to fix that, by adding the proper .global directive.

Summarized: in your assembly, change .global _main to .global factarial_asm.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top