News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Multi-module App Problems

Started by LoveToLrn, December 17, 2013, 03:42:18 PM

Previous topic - Next topic

LoveToLrn

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:

hutch--

Well, first tell us how you ave tried to link it together.

MichaelW

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.
Well Microsoft, here's another nice mess you've gotten us into.

dedndave

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

LoveToLrn

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?

dedndave

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

jj2007

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.

MichaelW

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.


Well Microsoft, here's another nice mess you've gotten us into.

dedndave

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