2

I have 2 files to compile. The first is main.c and the 2nd is a function that does sums and multiplications in assembly (work.s).

This is the code :

main.c file:

#include <stdio.h>

short work(); 

int main() {

    short z = work();
    printf("work(); -> %hd\n", z);
    return 0;
}

work.s file:

.globl work;

work :

    xorl %eax,%eax;
    xorl %ecx,%ecx;
    movw $20,%ax;
    subw $2,%ax;
    movw $7,%cx;
    addw $3,%cx;
    movw $10,%cx;
    subw $3,%cx;
    shl $1,%cx;
    addw %cx,%ax;
    ret;

From command line using gcc : gcc -m32 main.c work.s -o main

This is the output :

Undefined symbols for architecture i386:

"_work", referenced from: _main in main-fbbcca.o

ld: symbol(s) not found for architecture i386

clang: error: linker command failed with exit code 1 (use -v to see invocation)

While on Linux with same files and commands it works, why and how I can fix it?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
feded
  • 109
  • 2
  • 13

2 Answers2

3

Maybe change your global to the name gcc is looking for?

.globl _work;

_work :
       ...

There are other approaches, too:

https://montcs.bloomu.edu/~bobmon/Code/Asm.and.C/C-asm/Asm-C-example0.shtml

<= Different compiler, same principles...

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • It works thank you,I'm studying assembly for an exam and my prof explained it in this way on Linux so I have to follow his approach but I'll keep it in mind :). – feded Jun 08 '18 at 15:48
  • 2
    @feded Linux and macOS have different symbol decoration schemes. That's why you need an underscore on macOS but not on Linux. – fuz Jun 08 '18 at 18:31
  • @feded: tuz is correct. Different platforms and different compilers simply have different "symbol decoration schemes". Look here for further discussion: [Why do C compilers prepend underscores to external names?](https://stackoverflow.com/questions/2627511/). – paulsm4 Jun 10 '18 at 17:21
  • @paulsm4 Thanks,I didn't know that but however I don't understand why Mac needs of underscore in .s files and Linux doesn't . – feded Jun 11 '18 at 10:42
  • It's not just "macOS vs. Linux". *ANY* combination of platform (e.g. Windows vs. BSD) or compiler (e.g. gcc vs. CLang) can "do it differently". FYI, gcc lets you control the behavior with `-fleading-underscore` and `-fnoleading-underscore` compiler switches: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html – paulsm4 Jun 11 '18 at 16:15
2

In work.s, change work to _work both places it appears. The compiler prefixes an underscore to C names. Assembly language is more bare bones, so you have to prefix the underscore yourself.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • I wrote < stdio.h > because if I write it without space it disappear and the #includes becomes INCLUDES in bold, don't know why.My code is #include . – feded Jun 08 '18 at 15:42