Author Topic: Compiling/linking nasm & C  (Read 9826 times)

nobody

  • Guest
Compiling/linking nasm & C
« on: November 24, 2008, 05:32:53 PM »
I need to code a couple of short .asm functions that will be called by C and have pulled an example off the web. I'm using Fedora 9 and gcc. I'm getting several undefined references and I'm not sure why.

Here's my compile, followed by the program listings:

[michael@localhost ~]$ nasm -f elf maxofthree.asm -o maxofthree.o
[michael@localhost ~]$ gcc -c callmaxofthree.c -o callmaxofthree.o
[michael@localhost ~]$ gcc callmaxofthree.o maxofthree.o -o callmaxofthree
callmaxofthree.o: In function `main':
callmaxofthree.c:(.text+0x29): undefined reference to `maxofthree'
callmaxofthree.c:(.text+0x55): undefined reference to `maxofthree'
callmaxofthree.c:(.text+0x81): undefined reference to `maxofthree'
callmaxofthree.c:(.text+0xad): undefined reference to `maxofthree'
callmaxofthree.c:(.text+0xd9): undefined reference to `maxofthree'
callmaxofthree.o:callmaxofthree.c:(.text+0x105): more undefined references to `maxofthree' follow
collect2: ld returned 1 exit status
[michael@localhost ~]$ cat callmaxofthree.c
/*
 * callmaxofthree.c
 *
 * Illustrates how to call the maxofthree function we wrote in assembly
 * language.
 */

#include

int maxofthree(int, int, int);

int main() {
    printf("%d\n", maxofthree(1, -4, -7));
    printf("%d\n", maxofthree(2, -6, 1));
    printf("%d\n", maxofthree(2, 3, 1));
    printf("%d\n", maxofthree(-2, 4, 3));
    printf("%d\n", maxofthree(2, -6, 5));
    printf("%d\n", maxofthree(2, 4, 6));
    return 0;
}

[michael@localhost ~]$ cat maxofthree.asm
; ----------------------------------------------------------------------------
; maxofthree.asm
;
; NASM implementation of a function that returns the maximum value of its
; three integer parameters.  The function has prototype:
;
;   int maxofthree(int x, int y, int z)
;
; Note that only eax, ecx, and edx were used so no registers had to be saved
; and restored.
; ----------------------------------------------------------------------------   

global   _maxofthree

section .text
_maxofthree:
   mov   eax, [esp+4]
   mov   ecx, [esp+8]
   mov   edx, [esp+12]
   cmp   eax, ecx
   cmovl   eax, ecx
   cmp   eax, edx
   cmovl   eax, edx
   ret

[michael@localhost ~]$

nobody

  • Guest
Re: Compiling/linking nasm & C
« Reply #1 on: November 24, 2008, 06:48:11 PM »
Unlike most varieties of C, ELF doesn't want underscores on externals/globals. I think if you remove the underscore from "_maxofthree" in your .asm file, it will work.

Nasm has a built-in, per-output-format macro that will deal with this:

__NASM_CDecl_ _maxofthree

first thing in your .asm file, will remove the leading underscore in -f elf[32|64], and doesn't do a damn thing in other output formats. We can reclaim a bit of C's vaunted "portability" that way.

Another way to do it, is to write the .asm file without underscores, and add "--prefix _" to Nasm's command line if you want it for non-ELF.

Nice example!

Best,
Frank

nobody

  • Guest
Re: Compiling/linking nasm & C
« Reply #2 on: November 24, 2008, 07:53:46 PM »
Problem solved by taking out BOTH of the underscores. I saw another thread where that was suggested but only removed one. Thank you!

However, your suggestion to add the line to the beginning of the .asm file resulted in this error. Did I do something wrong?

[michael@localhost ~]$ nasm -f elf maxofthree.asm -o maxofthree.o
maxofthree.asm:1: error: parser: instruction expected
[michael@localhost ~]$ cat maxofthree.asm
__NASM_CDecl_ _maxofthree
; ----------------------------------------------------------------------------
; maxofthree.asm
;
; NASM implementation of a function that returns the maximum value of its
; three integer parameters.  The function has prototype:
;
;   int maxofthree(int x, int y, int z)
;
; Note that only eax, ecx, and edx were used so no registers had to be saved
; and restored.
; ----------------------------------------------------------------------------   

global   _maxofthree

section .text
_maxofthree:
   mov   eax, [esp+4]
   mov   ecx, [esp+8]
   mov   edx, [esp+12]
   cmp   eax, ecx
   cmovl   eax, ecx
   cmp   eax, edx
   cmovl   eax, edx
   ret

[michael@localhost ~]$

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Compiling/linking nasm & C
« Reply #3 on: November 24, 2008, 08:15:31 PM »
I think I spelled it wrong - "__NASM_CDecl__" (two underscores front and back)... but I still can't get it to work as expected (perhaps that's why it's not documented...). Never mind...

But I got a chance to test it, and it works great removing the underscores "by hand" (yeah, both in the "global" declaration and the label itself). Nice example!

Best,
Frank