Author Topic: Linking a NASM-compiled object to other software  (Read 2975 times)

Offline VPa

  • Jr. Member
  • *
  • Posts: 2
Linking a NASM-compiled object to other software
« on: June 08, 2016, 03:19:46 PM »
Hi,

When you compile a module with NASM and when would like to include it as a part of a larger program written in, say C, you have to communicate the calling convention somehow, unless there is some way to bypass type checking. For example, your assembly routine probably declares something like this:

    global _MyFunction

    _MyFunction:
         ; Assembly instructions here


whereas your C program could do something like this:

    int MyFunction(int value);   /* The prototype */

    int theKeyValue = MyFunction(theSeedValue); /* A call to the external function: */


.. and then you also specify the location of the module to your linker. Now, in order for that to work, the (_)MyFunction should somehow be declared to satisfy the "int MyFunction(int)" prototype.

Can this be done in NASM?

If not, is there some way around it, such as bypassing the typechecking of the C compiler?  I know that if, on Windows, you link the NASM-produced code into a DLL, there the function entries can be unqualified so that runtime linking to them can be done. But I'd prefer compile-time linking with typical, relatively small assembly modules.

Thanks for any hints!

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Linking a NASM-compiled object to other software
« Reply #1 on: June 10, 2016, 09:38:32 AM »
Try reading Section 9.1.2, Section 11.3, and Section 11.4 of the NASM User Manual.

A quick example might help.

Code: (addThree.asm) [Select]
BITS 32

SECTION .text
GLOBAL addThree
addThree:
enter 0, 0
mov eax, [ebp + 8]
add eax, 3
leave
ret

Code: (demo.c) [Select]
#include <stdio.h>

extern int addThree(int);

int main (void) {
printf ("addThree(5) = %d\n", addThree(5));
return (0);
}

Code: (Debian Linux Terminal) [Select]
$ nasm -felf addThree.asm -o addThree.o
$ gcc demo.c addThree.o -o demo
$ ls
addThree.asm  addThree.o  demo  demo.c
$ ./demo
addThree(5) = 8
$

As you already know, you have to add the underscores '_' on windows, but I hope this gives you an idea.

About Bryant Keller
bkeller@about.me

Offline VPa

  • Jr. Member
  • *
  • Posts: 2
Re: Linking a NASM-compiled object to other software
« Reply #2 on: June 16, 2016, 03:55:00 PM »
Hi,

Thanks for the advice, but calling convention is not exactly what I intended to ask about. My inquiry was about how to make NASM encode function entries in object files so that a linker can recognize them to match a given function prototype -- that is, an entry in another object file produced by a C compiler. I encountered this problem with Borland's compiler environment, and I understand that this is probably dependent on linker and object file format, but it is also a general problem to be solved.

Does NASM assume that linkers generally accept entries just by name, possibly a mangled one?  Or is there a way to modify entries by e.g. "meta-information" that could help in getting function entries matched?

Thanks in advance.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Linking a NASM-compiled object to other software
« Reply #3 on: June 23, 2016, 09:05:46 AM »
A C compiler shouldn't be modifying the symbol's name. A C++ compiler, however, does (as a general solution for supporting overloaded functions). It's a bit problematic since there is no specific standard by which the C++ compilers will mangle the symbols either. Luckily, many compilers support a way to turn off name mangling; in the below code for demo.c changing the line from:

Code: [Select]
extern int addThree(int);
to:

Code: [Select]
extern "C" int addThree(int);
might actually do the trick. This works with GCC compiled C++ sources to make the asm code work.

About Bryant Keller
bkeller@about.me