Hey Guys, I am having trouble getting my first multi-module application to link properly.
Based on the material I have seen so far this code should work:
procedures.inc:
testerPro PROTO,
var1:DWORD
testerPro20 PROTO,
var20:DWORD
SetColor2.asm:
INCLUDE procedures.inc
.code
testerPro PROC, var1:DWORD
mov eax,0
ret 4
testerPro ENDP
testerPro20 PROC, VAR20:DWORD
mov ebx,0
ret 4
testerPro20 ENDP
END
SetColor_main_2.asm:
TITLE Main Procedure for our first multi-modular program
.586
.model flat,stdcall
OPTION casemap:none
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
INCLUDE \masm32\include\masm32rt.inc
INCLUDE procedures.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
var3 DWORD 0
var4 DWORD 0
.code
main:
INVOKE testerPro, var3
INVOKE testerPro20, var4
END main
The point of this was simply to understand the syntax for a multi-module program,
that uses the INVOKE,PROC(extended syntax),PROTO directives instead of using
the call and EXTERN syntax, and to get it to assemble and link properly.
Any help is appreciated, thanks guys! :biggrin:
Well, first tell us how you ave tried to link it together.
In SetColor_main_2.asm and SetColor2.asm you need:
.586
.model flat,stdcall
OPTION casemap:none
Or:
INCLUDE \masm32\include\masm32rt.inc
But not both. And you can assemble and link with a batch file like this:
\masm32\bin\ml /c /coff SetColor2.asm
pause
\masm32\bin\ml /c /coff SetColor_main_2.asm
pause
\masm32\bin\Link /SUBSYSTEM:CONSOLE SetColor_main_2.obj SetColor2.obj
pause
Note on the linker command line that the object module for the main module is listed first.
This might be a better exercise if you coded the procedures to return the values they were passed, passed unique values to each one, then displayed the return values. To display the return values you will need to include masm32rt.inc in the main module. If you are not sure how to return a value, see Agner Fog's calling_conventions.pdf, available here (http://www.agner.org/optimize/).
you have unnecessary commas in PROTO and PROC lines
testerPro PROTO var1:DWORD
testerPro20 PROTO var20:DWORD
also, the assembler will calculate the number of bytes to pop for RET
if you assign the number, the rest of the EPILOGUE is not assembled, as desired
testerPro PROC var1:DWORD
mov eax,0
ret
testerPro ENDP
testerPro20 PROC VAR20:DWORD
mov ebx,0
ret
testerPro20 ENDP
the last proc uses EBX without preserving it
in some cases, that's ok - but windows Application Binary Interface rules:
EAX, ECX, EDX may be volatile across calls
EBX, EBP, ESI, EDI should be preserved across calls
the direction flag should be cleared on entry, and on exit - if you set it, clear it when done
windows API functions generally follow those rules, and we try to write most functions the same way
one way to preserve EBX:
testerPro20 PROC USES EBX VAR20:DWORD
mov ebx,0
ret
testerPro20 ENDP
you should terminate the program with ExitProcess
main:
INVOKE testerPro, var3
INVOKE testerPro20, var4
INVOKE ExitProcess,0
END main
you will have to INCLUDE some files, as Michael suggested, to use ExitProcess
I tried to link via Console Assemble and Link.
The error I am getting is:
Set_Color_main_2.obj: error LNK2001: unresolved external symbol _testerPro@4
Set_Color_main_2.obj: error LNK2001: unresolved external symbol _testerPro20@4
Also how does the linker know to link the definitions of both my procedures in the Set_Color2.asm file
to the proto types in the procedures.inc file so that my Set_Color_main_2.asm isn't only seeing the
PROTO declarations in procedures.inc?
can you attach the full project ?
if you are trying to link more than one OBJ file, you may have to write a special batch file
probably the easiest way is to put your "external" OBJ's into a static library, then INCLUDE and INCLUDELIB
attached is an example with a small static library
the batch file builds the library, testlib.lib
notice that PROC's are PUBLIC, by default
DATA defintions are not, and must be made public using EXTERNDEF
once you have created the LIB file, you may build the console application, libtest.exe using the normal method
Quote from: LoveToLrn on December 18, 2013, 08:43:31 AM
I tried to link via Console Assemble and Link.
Copy the batch code in Michael's post into a file named MyProject.bat and run it from a DOS prompt.
Quote from: LoveToLrn on December 18, 2013, 08:43:31 AM
Also how does the linker know to link the definitions of both my procedures in the Set_Color2.asm file
to the proto types in the procedures.inc file so that my Set_Color_main_2.asm isn't only seeing the
PROTO declarations in procedures.inc?
As Dave stated, PROC's are PUBLIC by default. So ML places information in the object module that the linker uses to find the procedures and link with them (and basically the same for the libraries). If I change the visibility of the second procedure to PRIVATE:
INCLUDE \masm32\include\masm32rt.inc
INCLUDE procedures.inc
.code
testerPro PROC var1:DWORD
mov eax,0
ret 4
testerPro ENDP
OPTION PROC:PRIVATE
testerPro20 PROC VAR20:DWORD
mov ebx,0
ret 4
testerPro20 ENDP
END
Then the linker returns:
C:\masm32\My\_junk\multimod>\masm32\bin\Link /SUBSYSTEM:CONSOLE SetColor_main_2.
obj SetColor2.obj
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
SetColor_main_2.obj : error LNK2001: unresolved external symbol _testerPro20@4
SetColor_main_2.exe : fatal error LNK1120: 1 unresolved externals
BTW, if you place an appropriate makeit.bat in your project directory, QE has a command on the Project menu that will run it.
here is another example - this one uses 2 seperate modules to build the static library
running the MakeLib batch file will assemble Module1.asm and Module2.asm, then link them to create MyLib.lib
once you have the library built, you can assemble the console mode TestProgram.asm file, normally