NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: gareth stokes on February 16, 2009, 11:25:22 AM
-
I'm trying to link some assembly written with nasm in with some c code that gets compiled with gcc.
unfortunately this is the error i get when linking the assembly and c object files together:
Undefined symbols:
"_asm_mod_array", referenced from:
_main in main.o
any help would be appreciated...
assembly.asm
--------------------------------
global asm_mod_array
asm_mod_array:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov ecx, [ebp+12]
xor edi, edi
start_loop:
cmp ecx, edi
je loop_exit
mov edx, [eax+edi*4]
lea edx, [5+edx*2]
mov [eax+edi*4], edx
inc edi
jmp start_loop
loop_exit:
mov esp, ebp
pop ebp
ret
main.c
-------------------------
#include
/* prototype for asm function */
int* asm_mod_array(int *ptr,int size);
int main()
{
int fren[5]={ 1, 2, 3, 4, 5 };
/* call the asm function */
asm_mod_array(fren, 5);
return 0;
}
bash commands
-------------------------
nasm -f macho asm.asm
gcc -c main.c
ld asm.o main.o
-
Looks like "-f macho" needs underscores on global/extern symbols. Try adding "--prefix _" to Nasm's command line (or add an underscore "by hand" to asm_mod_array - both the "global" declaration and the label). You may need to preserve edi across the function, too.
Nice to see someone using Nasm on Mac!
Best,
Frank
-
thanks for the help, managed to get a bit further by using the --prefix command
nasm -f macho --prefix _ asm.asm
unfortunately ld is still throwing errors...
ld: could not find entry point "start" (perhaps missing crt1.o)
I don't understand why its looking for a entry point if the main.c file already has one?
-
Ah, I see what's happening... I think...
The "entrypoint" ld is looking for is "_start". You've got "_main", but "_main" isn't the "real" entrypoint. There's some "startup" code - in "crt0.o" or similar (apparently crt1.o, in this case) - which contains "_start", and which calls "_main", after doing some "housekeeping". Gcc links "crt?.o" (and libc) without being told to. This is the advantage to using gcc, even if there's no .c to compile - gcc "knows where the bodies are buried" (knows what need to be linked, and the path to it), and can invoke ld with the correct command line.
Doing "gcc -c main.c" creates "main.o" - fine so far. Nasm creates your "asm.o" - fine so far. But to link the whole mess together, we'd have to do "ld main.o asm.o /path/to/crt1.o" (I'd add "-o exename", too, or it'll produce "a.out"... I think) - possibly other stuff gets linked, too - I don't think so, in this case...
You can compile "main.c" separately, as you're doing, and then "gcc main.o asm.o [-o exename]" or you can do it in one step: "gcc main.c asm.o" ("asm.asm" has to be assembled to "asm.o" first, obviously).
You gave us all the information to figure this out in your first post - I just missed it. Sorry.
The above all applies to Linux. BSD is "like" Linux (or vise versa), and MacOSX is "like" BSD... except that there are some differences (like underscores). I *think* the above will work for MacOSX... except for some possible subtle differences - which I'll only know about if someone tells me. So I really appreciate your feedback!
Best,
Frank