Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

32-bit DLLs and TASM 5.0

77 views
Skip to first unread message

Ian McLaren

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

Help! I need to program a 32-bit DLL using TASM 5. I've written several
16-bit DLLs, so this is not a general *What's a DLL?* question.

In doing a DejaNews search, I've noticed several questions over the last
few months requesting info on how to program simple 32-bit DLLs using
TASM 5, but not come across any direct answers. Adam Stanislav's page at
www.geocities.com/SiliconValley/Heights/7394/ gives an example
(crc32.zip) for MASM 6.1, but I can't get it to assemble with TASM 5
(even using the MASM or QUIRKS directives). The Borland TASM 5 example
DLL is 16-bit. Their 32-bit example is an EXE app not a DLL -- I appear
to be stuck in the middle and know I'm not the only one!

I have been writing 16-bit DLLs using TASM 3.2 for a couple of years,
and they work fine called from Visual Basic 3. I now need to port my
applications to Visual Basic 5, so of course either need to thunk (which
I'd rather not do) or write 32-bit DLLs. I can write what I *think* is a
32-bit DLL in TASM 5, and have it assemble and link OK, but VB5 says
*File not Found* (it really _is_ there!), which I know is what it does
when a 16-bit DLL is called by mistake.

Here's an example of the simplest 16-bit DLL I have (it beeps to show
that it's working..) -- it's only 27 lines including spaces:

Begin Listing of DLLbeep.asm:
;---------------------------------------------
;DLLbeep.ASM
MODEL SMALL
.386
INCLUDELIB IMPORT ;Windows library
EXTRN MESSAGEBEEP:FAR

codeseg
LibMain PROC PASCAL FAR
PUBLIC PASCAL LibMain
ARG
@@hInstance:WORD,@@wDataSeg:WORD,@@wHeapSize:WORD,@@lpszCmdLine:DWORD
mov ax,1 ;signals successful initialization
ret
LibMain ENDP

wep PROC WINDOWS PASCAL FAR
PUBLICDLL PASCAL WEP
ARG @@nParameter
mov ax,1 ;signals successful de-initialization
ret
wep ENDP

MyBeep PROC WINDOWS PASCAL FAR
PUBLICDLL PASCAL MyBeep
mov ax,-1
call MESSAGEBEEP PASCAL,ax
ret
MyBeep ENDP
END
;--------------------------------------------
End Listing DLLbeep

OK -- the DEF file, DLLbeep.DEF, is:
----------------------------------------------
LIBRARY DLLBEEP
EXETYPE WINDOWS
CODE MOVEABLE DISCARDABLE
DATA MOVEABLE MULTIPLE DISCARDABLE
STACKSIZE 5120
-----------------------------------------------

I assemble with TASM 3.2 and link with TLINK:

TASM DLLbeep
TLINK DLLbeep.obj,DLLbeep,,import.lib,DLLbeep.def

OK, so this all works. I can call MyBeep from Visual Basic 3 and the
speaker beeps. My real 16-bit DLLs are a few thousand ASM source lines
long, but they all start here. I hope anyone just starting out in ASM
DLL programming can use this template!

So, after all that, is there anyone out there who can perhaps provide me
with an equivalent, really simple 32-bit DLL source listing for TASM 5,
so I can move on from there? I would be happy enough to put the info up
on a web site later (with attribution of course) and link to suitable
other ASM-friendly URLs.

Thanks in advance for any help!

Ian McLaren
imcl...@california.com


Ian McLaren

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

(I'm reposting this due to problems with my news server -- sorry if it
appears as a duplicate)

Please Help! I need to program a 32-bit DLL using TASM 5. I've written

several 16-bit DLLs, so this is not a general *What's a DLL?* question.

In doing a DejaNews search, I've noticed several questions over the last

few months requesting info on how to program simple 32-bit DLLs using

TASM 5, but not come across any direct answers. Adam Stanislav's page at

www.geocities.com/SiliconValley/Heights/7394/ gives an example

(crc32.zip) for MASM 6.1, but I can't get it to assemble with TASM 5.

The Borland TASM 5 example DLL is 16-bit. Their 32-bit example is an EXE

app not a DLL -- I appear to be stuck in the middle and I know I'm not

the only one!

I have been writing 16-bit DLLs using TASM 3.2 for a couple of years,

and they work fine called from Visual Basic 3. I now need to port my

applications to Visual Basic 5, so of course either need to thunk (which

I'd rather not do) or write 32-bit DLLs. I can write what I *think* is a

32-bit DLL in TASM 5, but VB5 says *File not Found* (it really _is_

there!), which I know is what it does when a 16-bit DLL is called by

mistake.

Here's an example of the simplest 16-bit DLL I have (it beeps to show

that it's working..) -- it's only 27 lines including spaces, so forgive

the listing:

Begin Listing of DLLbeep.asm:

;---------------------------------------------

;DLLbeep.ASM

MODEL SMALL

.386

INCLUDELIB IMPORT ;Windows library

EXTRN MESSAGEBEEP:FAR

codeseg

LibMain PROC PASCAL FAR

PUBLIC PASCAL LibMain

ARG

ret

LibMain ENDP

PUBLICDLL PASCAL WEP

ARG @@nParameter

ret

wep ENDP

PUBLICDLL PASCAL MyBeep

mov ax,-1

call MESSAGEBEEP PASCAL,ax

ret

MyBeep ENDP

END

;--------------------------------------------

End Listing DLLbeep

----------------------------------------------

LIBRARY DLLBEEP

EXETYPE WINDOWS

CODE MOVEABLE DISCARDABLE

DATA MOVEABLE MULTIPLE DISCARDABLE

STACKSIZE 5120

-----------------------------------------------

TASM DLLbeep

TLINK DLLbeep.obj,DLLbeep,,import.lib,DLLbeep.def

with an equivalent really simple 32-bit DLL source listing for TASM 5? I

Morten Elling

unread,
Apr 15, 1998, 3:00:00 AM4/15/98
to

> need to program a 32-bit DLL using TASM 5.
[...]

> port my applications to Visual Basic 5,


Here's a Win32 DLL example written for TASM 4+, showing

- Functions exported by TASM's PUBLICDLL directive (which
puts EXPDEF records in the .obj file), eliminating the
need for an EXPORTS section in the .def file.

- An entry/exit function, which isn't required in a Win32
DLL but if present it must take the form defined by the
DllEntryPoint 'API'. It should be accompanied by an
INITGLOBAL or INITINSTANCE specifier in the .def file's
LIBRARY statement.

- A shared data segment, in case you insist on sharing data
this way. Requires a SEGMENTS statement in the .def file
to mark it as shareable in the PE header, not to mention
the extra work involved when modifying shared data in a
multi-processor environment like NT.


The import libraries produced by TASM's IMPLIB utility are
in OMF format and use undecorated names for STDCALL symbols,
as used by Borland tools. Microsoft's VC++ tools (don't know
about VB5) expect COFF format .obj/.lib files and use name-
mangling on C __stdcall symbols (prepend '_' and append '@'
followed by the byte size of arguments as decimal ASCII).

If your compiler comes with an IMPLIB utility, run it on the
.dll file to get the .lib file you need for linking. If not,
you have the option of using an IMPORTS section in caller's
.def file; don't forget to prototype imported DLL functions
in caller's module:
IMPORTS
DLL32S.GetDllInst
DLL32S.ShowDllCount


See also tlink.txt, tlib.txt, tdump.txt in \tasm\doc\, and
the appropriate megabytes of compiler and Win32 docs.


------- dll32s.asm -------
ideal
%title "Win32 DLL sample"
p386n
model FLAT, stdcall
ifdef DWIM
nosmart ; No optimization of LEA and
endif ; signed boolean instructions

DATASEG ; Instance data
g_hInst dd 00h
g_Ticks dd ?

segment SDATA '.Shared' use32 ; Shared data
align 4
sg_Count dd 00h
ends SDATA


CODESEG
publicdll GetDllInst, ShowDllCount
extrn C wsprintfA :proc, MessageBoxA :proc, GetTickCount :proc
extrn InterlockedIncrement :proc, InterlockedDecrement :proc

;
; HINSTANCE WINAPI GetDllInst( void );
;
align 4
proc GetDllInst
mov eax, [g_hInst]
RET
endp


;
; UINT WINAPI ShowDllCount( UINT anumber );
;
align 4
proc ShowDllCount uses ebx edi, anumber
local @@buf:byte:128

CONST
@@boxCap db "Hello from the DLL", 0,0
@@boxTxt db "I ticked in at # %u ", 0ah
db "as copy # %i of this library, ", 0ah
db "and caller sent me # %u.", 0

CODESEG
mov eax, [anumber]
mov ebx, [sg_Count]
lea edi, [@@buf]
call wsprintfA C, edi, \ ; Note C language modifier
offset(@@boxTxt), \
[g_Ticks], ebx, eax
call MessageBoxA, 0, edi, \
offset(@@boxCap), \
(00h+40h+10000h) ; MB_OK OR MB_ICONINFORMATION
; OR MB_SETFOREGROUND
mov eax, ebx ; Return sg_Count
RET
endp


;
; Entry/exit point, cf. DllEntryPoint
;
proc DllMayn hinstDll, fdwReason, fImpLoad
mov ecx, [fdwReason]
lea edx, [sg_Count]
jecxz @@pdet ; DLL_PROCESS_DETACH = 0
loop @@ret ; DLL_PROCESS_ATTACH = 1
push [hinstDll]
pop [g_hInst]
call InterlockedIncrement, edx
call GetTickCount
mov [g_Ticks], eax
mov eax, 1 ; Return TRUE
jmp short @@ret
@@pdet: call InterlockedDecrement, edx
@@ret: RET
endp

END DllMayn


------- dll32sgo.asm -------
ideal
p386n
model NT FLAT, stdcall

UDATASEG ; TLINK32 gets confused
dummy dd ? ; if there's no data

CODESEG
extrn GetTickCount:proc ; From KERNEL32.DLL
extrn ShowDllCount:proc ; From DLL32S.DLL
startupcode
call GetTickCount
call ShowDllCount, eax
exitcode 0

END


------- dll32s.def -------
library initinstance
segments
SDATA class '.Shared' shared


------- dll32smk.bat -------
@echo off
:
: Builds a PE format .DLL, using IMPLIB to produce the
: associated import library, and a PE .EXE to drive it.
: Tested with TASM32 4.1 and 5.0r; TLINK32 1.6.71.0.
:
set D=dll32s
set E=dll32sgo

tasm32 /ml/la/t %D%+%E%;
tlink32 /c/x /Tpd/aa /V4.0 %D%,,,import32.lib,%D%.def,
rem /f Import by name
implib /f/c %D%.lib %D%.dll
tlink32 /c/x /Tpe/aa /V4.0 %E%,,,%D%.lib+import32.lib,,

: Reduce PE sizes (optional)
echo dummy rcdata { } >dummy.rc
brc32 /fe%D%.dll dummy.rc
brc32 /fe%E%.exe dummy.res
-------


April 15th, 1998
Morten Elling


0 new messages