NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: nobody 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 ~]$
-
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
-
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 ~]$
-
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