I imagine this question has come up before, although I did search around a bit, both online and this forum but couldn't seem to immediately find anything.
I'm trying to learn how to use multiple modules for when I start working on some slightly larger assembly projects. Coming from a C/C++ background, I have been used to compiling each .c file into an object file, and then linking them all together into an executable. I'm trying to basically do the same thing here, but my main module gives an external symbol error when trying to call a procedure defined in another module.
My main module (test.asm):
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
externdef TestFunction:near
.data
msg db "Hello, world!",0
msg_caption db "Test",0
.code
start:
mov eax,MB_OK
push eax
lea eax,msg_caption
push eax
lea eax,msg
push eax
xor eax,eax
push eax
call MessageBox
call TestFunction
mov eax,0
push eax
call ExitProcess
end start
and then the other module (proc.asm):
.386
.model flat,stdcall
.code
TestFunction proc
push ebp
mov ebp, esp
mov esp, ebp
pop ebp
ret 0
TestFunction endp
end
I am compiling everything like so:
ml /c /coff test.asm
ml /c /coff proc.asm
which both work fine. This, however doesn't:
link /SUBSYSTEM:console /LIBPATH:f:\masm32\lib /ENTRY:start test.asm proc.asm
giving the following error:
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
test.obj : error LNK2001: unresolved external symbol _TestFunction
test.exe : fatal error LNK1120: 1 unresolved externals
Am I missing something obvious here?
http://en.wikipedia.org/wiki/Name_mangling
Basically, either add a 'stdcall' or rename your function with the underscore
Well, I have the stdcall up near the top of both modules, if that is what you are referring to. And, I already tried adding an underscore to the procedure name in 'proc.asm' and re-compiling it, but it still gave the same error.
I recommend you to use PROTO instead of EXTERNDEF:
TestFunction PROTO
Thanks, qWord. Using the PROTO method worked fine.
Yes, just tested that, qWord beat me to the post.
Also you might want to specify OBJ files in the LINK command line rather than ASM
ml -c -coff -Fl test.asm
ml -c -coff -Fl proc.asm
link /SUBSYSTEM:console /LIBPATH:\masm32\lib /ENTRY:start test.obj proc.obj
With "externdef TestFunction:near" test.obj looks like this
Disassembly
00000000 _start:
00000000 B800000000 mov eax,0
00000005 50 push eax
00000006 8D053E000000 lea eax,[3Eh]
0000000C 50 push eax
0000000D 8D0530000000 lea eax,[30h]
00000013 50 push eax
00000014 33C0 xor eax,eax
00000016 50 push eax
00000017 E8E4FFFEEF call _MessageBoxA@16
0000001C E8DFFFFDEF call _TestFunction
00000021 B800000000 mov eax,0
00000026 50 push eax
00000027 E8D4FFFCEF call _ExitProcess@4
With "TestFunction PROTO" test.obj looks like this
Disassembly
00000000 _start:
00000000 B800000000 mov eax,0
00000005 50 push eax
00000006 8D053E000000 lea eax,[3Eh]
0000000C 50 push eax
0000000D 8D0530000000 lea eax,[30h]
00000013 50 push eax
00000014 33C0 xor eax,eax
00000016 50 push eax
00000017 E8E4FFFEEF call _MessageBoxA@16
0000001C E8DFFFFDEF call _TestFunction@0
00000021 B800000000 mov eax,0
00000026 50 push eax
00000027 E8D4FFFCEF call _ExitProcess@4
While proc.obj looks like this
Disassembly
00000000 _TestFunction@0:
00000000 55 push ebp
00000001 8BEC mov ebp,esp
00000003 8BE5 mov esp,ebp
00000005 5D pop ebp
00000006 C3 ret
Yes, excellent point. In my haste to post this in order to get an answer, I obviously typed out the link line incorrectly.