News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Help needed to build a library of PROCs

Started by frktons, January 10, 2013, 12:38:32 PM

Previous topic - Next topic

frktons

Quote from: qWord on January 14, 2013, 06:17:00 AM
include file:
S struct
member1 DWORD ?
member2 DWorD ?
S ends

EXTERNDEF foo:S


some lib module:
.data
    foo S <>


Thanks qWord.

Quote from: MichaelW on January 14, 2013, 07:24:53 AM
We have somewhat of a terminology problem here. STRUCT is used to declare a structure, so it's a type declaration that can be used in a data definition, or as a template for accessing data, or in this case as a qualifiedtype in an EXTERNDEF statement, but only if at the point of usage the assembler recognizes the type. And AFAIK for the assembler to recognize a type it must be an intrinsic type, or a previously declared structure, union, or record, or a type previously defined with TYPEDEF.

Thanks Michael, I probably tried to use a struct [in an external module]
that was not correctly defined in that module, so at assembly time MASM
complained about it, the EXTERNDEF and the name of the struct were
not enough. Probably it is better just to pass the pointer to the area and
define the struct inside the called PROC:

main proc

area db 16 dup(?)
ptr_area dd area
...
INVOKE calledPROC, ptr_area
...



MyStruct STRUCT
     Field1  DWORD ?
     Field2  DWORD ?
     Field3  DWORD ?
     Field4  DWORD ?
MyStruct   ENDS

.data

.code

CalledPROC PROC PtrArea:DWORD

....

mov eax, PtrArea
ASSUME  eax:PTR MyStruct
mov [eax].Field1, "some"
mov [eax].Field2, "ASM "
mov [eax].Field3, "code"
mov [eax].Field4, "work"

ASSUME eax:NOTHING

CalledPROC ENDP
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

ok
probably something i suggested is not correct, here
that is to put the "includelib MyLib.lib" line in the INC file
if you remove that line from the INC file and put it in the program source file....

now, you can include the INC file in both the program source and the module source
the structure definition will be available for both sources

frktons

After a long process of testing, correcting, updating, the small
library is ready for the tests and comments.
Attached the sources, the lib, and a test program to use the PROCs
inside the LIB.

Any comment, suggestion, improvement is welcome.  :biggrin:
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

MichaelW

The example in the attachment declares a structure, along with an EXTERNDEF statement and a prototype, in an include file that is included in both modules, defines a structure variable and initializes it in the first module, then calls a procedure in the second module to display the initialized values. Instead of working through a pointer, the second module directly accesses the structure variable.
Well Microsoft, here's another nice mess you've gotten us into.

frktons

#49
Quote from: MichaelW on January 14, 2013, 11:57:45 AM
The example in the attachment declares a structure, along with an EXTERNDEF statement and a prototype, in an include file that is included in both modules, defines a structure variable and initializes it in the first module, then calls a procedure in the second module to display the initialized values. Instead of working throught a pointer, the second module directly accesses the structure variable.
Thanks Michael, your help has gone in the right direction.  :t
This time you answered to a previous question of mine, and
gave me a simple solution for something that was driving me mad.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

Adamanteus

Yes, if not follow good practice something in building libraries will go you mad. But everything genius is simple – so, batch build could be done by maker utility, and calling with differ options batch file. Develop of course better in IDE simple that easy work with files.
So, each library mought consist of standard catalogs structure :
Demo
   MyDemo
Doc
Include
Source
   MyModule
Test
   MyModule
In inc-files better to use PROTO keyword for PROCs, then EXTERNDEF.

Batch file :

@echo off

if not %1. == . set options=%1=1
if not %2. == . set options=%options% %2=1

nmake /f my-lib.mak LIBNAME=my-lib-ma %options%
if errorlevel 1 goto NO_MAKE

echo ----------------------------------------
echo Successful build of My-Lib v.1.0.0.0 :
echo ----------------------------------------
echo  Lib\
dir /B Lib\*.*
echo  Demo\
dir /B Demo\*.*
goto TERMINATOR

:NO_MAKE
echo -----------------------------------------
echo   Build of My-Lib v.1.0.0.0 not down !
echo -----------------------------------------
echo Check search includes path INCLUDES and
echo library files of MSVCLIBS and SDKLIBS.
echo -----------------------------------------

:TERMINATOR

Makefile is go by principle of building sources by whole catalogs :

PROJ          = My-Lib

MODEL         = F
PROCESSOR     = 6
ASMMACROS     =
LIBDIR        = Lib

asm           = ml
lib           = lib
link          = link

asmflags      = /c /nologo
libflags      =
linkflags     = /RELEASE /MACHINE:IX86 /DYNAMICBASE /NXCOMPAT /NOLOGO /MANIFEST:NO

!ifdef DEBUG
asmflags      = /Zi $(asmflags)
libflags      = $(libflags)
linkflags     = $(linkflags) /DEBUG
!else
asmflags      = $(asmflags)
libflags      = $(libflags)
linkflags     = $(linkflags) /LTCG
!endif

!if "$(MODEL)" == "F"
WIN32         = 1
asmflags      = $(asmflags) /Dmodl=FLAT /coff
!elseif "$(MODEL)" == "H"
asmflags      = $(asmflags) /Dmodl=HUGE
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "L"
asmflags      = $(asmflags) /Dmodl=LARGE
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "C"
asmflags      = $(asmflags) /Dmodl=COMPACT
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "M"
asmflags      = $(asmflags) /Dmodl=MEDIUM
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "T"
asmflags      = $(asmflags) /Dmodl=TINY
libflags      = $(libflags) /PAGESIZE:64
!else
! ERROR Model $(MODEL) - not supported !
!endif

!ifdef DEFFILE
linkflags     = $(linkflags) /DEF:..\$(DEFFILE)
DLL           = 1
dump          =
!else
dump          = dumpbin /exports $(LIBNAME).dll >$(LIBNAME).lst
!endif

!ifndef MSVCLIBS
MSVCLIBS      = "\MSVC\VC\Lib"
!endif

!ifndef SDKLIBS
SDKLIBS       = "C:\Program Files\Microsoft SDKs\Windows\v7.0\Lib"
!endif

!ifndef LIBDIR
LIBDIR        = Lib
!endif

!ifndef LIBNAME
LIBNAME       = $(PROJ)
!endif

!if "$(MODEL)" == "F"
WIN32         = 1
!else
! ERROR Model $(MODEL) - not supported !
!endif

!ifdef DLL
$(LIBDIR)\$(LIBNAME).dll : asmobj
$(rc) $(rcflags) $(LIBNAME).rc
@move $(LIBNAME).res $(LIBDIR) >NUL
@cd $(LIBDIR)
@dir *.obj /B >objects.rsp
@$(link) /SUBSYSTEM:WINDOWS /DLL $(linkflags) /LIBPATH:$(MSVCLIBS) /LIBPATH:$(SDKLIBS) /OUT:$(LIBNAME).dll $(LIBNAME).res $(OBJS) @objects.rsp
@del $(LIBNAME).res
@del objects.rsp
@del *.obj
@$(dump)
@cd ..
!else
$(LIBDIR)\$(LIBNAME).lib : asmobj
@cd $(LIBDIR)
@del My-Lib-DLL.obj
@dir *.obj /B >objects.rsp
@$(lib) $(libflags) /OUT:$(LIBNAME).lib @objects.rsp
@del objects.rsp
@del *.obj
@cd ..
! endif


asmobj :
@echo Assembling code $(PROJ) for Windows x86
@echo ------------------------------------------
@if not exist $(LIBDIR) md $(LIBDIR)
@cd Source
@cd MyModule
@dir *.asm /B >sources.rsp
@$(asm) $(asmflags) $(ASMMACROS) @sources.rsp
@del sources.rsp
@move *.obj ..\..\$(LIBDIR) >NUL
@cd ..
@cd ..

frktons

Hi Adamanteus,
for building all at once a library with many PROCs, the use of a make file
is a good idea. But I'm going to develop each single PROC, test it and when
ready I'm going to insert it inside the LIB, adding it to pre-existent PROCs.

I need probably an interactive interface to select single PROCs, and give the
command to assemble, insert, update... the LIB.
For the time being I'd better build this interactive tool that executes the batch
files I already prepared, than to start a new study on make files.

First things first, and so far I need more this interactive tool than make files.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

you could do something like Hutch does to build the masm32 library
have a look at the make.bat file that is a remnant in the masm32\m32lib folder   :P
he simply does a DIR into a text file, then uses that text file as a response file for the assembler
when he gets to the link command, he just uses "*.obj"
it's a short batch file that does a lot of stuff

frktons

Quote from: dedndave on January 15, 2013, 11:58:37 AM
you could do something like Hutch does to build the masm32 library
have a look at the make.bat file that is a remnant in the masm32\m32lib folder   :P
he simply does a DIR into a text file, then uses that text file as a response file for the assembler
when he gets to the link command, he just uses "*.obj"
it's a short batch file that does a lot of stuff

Yes, this a good stuff for building a LIB all at once. Not my case however.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

Adamanteus

#54
I'd say that library anyway building all at once - after you made procedure and putted to it.
So maybe for stable part of library use common methods, and for adding to it developing part use normal makefile with timestamp checks procedures  :

PROJ          = My-Lib

OBJECTS       = Source\MyModule\Proc1.obj \
Source\MyModule\Proc2.obj

MODEL         = F
PROCESSOR     = 6
ASMMACROS     =

asm           = ml
lib           = lib

asmflags      = /c /nologo
libflags      =

!ifdef UNICODE
ASMMACROS     = $(ASMMACROS) /DUNICODE
!endif

!ifdef DEBUG
asmflags      = /Zi $(asmflags)
libflags      = $(libflags)
!else
asmflags      = $(asmflags)
libflags      = $(libflags)
!endif

!ifndef LIBDIR
LIBDIR        = Lib
!endif

!ifndef LIBNAME
LIBNAME       = $(PROJ)
!endif

!if "$(MODEL)" == "F"
WIN32         = 1
asmflags      = $(asmflags) /coff
!elseif "$(MODEL)" == "H"
asmflags      = $(asmflags) /Dmodl=HUGE
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "L"
asmflags      = $(asmflags) /Dmodl=LARGE
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "C"
asmflags      = $(asmflags) /Dmodl=COMPACT
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "M"
asmflags      = $(asmflags) /Dmodl=MEDIUM
libflags      = $(libflags) /PAGESIZE:64
!elseif "$(MODEL)" == "T"
asmflags      = $(asmflags) /Dmodl=TINY
libflags      = $(libflags) /PAGESIZE:64
!else
! ERROR Model $(MODEL) - not supported !
!endif

$(LIBDIR)\$(LIBNAME).lib : $(OBJECTS)
!@copy $** $(LIBDIR) >NUL
!@$(lib) $(libflags) /REMOVE:$(**F) $*.lib
@cd $(LIBDIR)
@$(lib) $(libflags) $(LIBNAME).lib $(**F)
@del *.obj
@cd ..

.asm.obj :
@$(asm) $(asmflags) $(ASMMACROS) /Fo$*.obj $*.asm