I'm new to the forum and asm. I have written some basic programs and procedures and now want to start making some simple libraries.
For example a math library with functions like fib and fac.
So I have a file called math.asm and a file called test.asm. test.asm uses fac from math.asm.
if i try to include math.asm like this:
include C:\masm32\progs\math.asm
I get an error:
test.asm(18) : fatal error A1000: cannot open file : C:\masm32\progs\math.asm
I have also tried commenting out everything besides the procedures in math.asm(ie all the includes) but then I get:
Assembling: math.asm
math.asm(20) : error A2034: must be in segment block : fac
math.asm(21) : error A2085: instruction or register not accepted in current CPU
mode
math.asm(22) : error A2085: instruction or register not accepted in current CPU
mode
math.asm(23) : error A2034: must be in segment block
math.asm(24) : error A2085: instruction or register not accepted in current CPU
mode
math.asm(25) : error A2034: must be in segment block : $$$00001
math.asm(25) : error A2034: must be in segment block
math.asm(26) : error A2034: must be in segment block : $$$00001
math.asm(26) : error A2034: must be in segment block
math.asm(27) : fatal error A1010: unmatched block nesting : fac
C:\masm32\progs\libs>
So:
1. should libraries just contain the procedure implementations or also stuff like .386, .model etc?
2. how do I import and link together files?
Code is here:
http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4232#a4232
Comments on the actual code quality is always welcome but most importantly I want to know how to assemble and link several files together.
And btw:
asm is fun!
I have no idea why you commented out a bunch of the lines cause when you uncomment it it assembles and links fine. Just put it into QEditor then Project >> Console Assemble & Link
http://pastebin.com/m1712b032
Ooops I misread.. if you want a DLL then try Code >> Create New DLL. The comment at the bottom describes how you can add procedures that can be exported and used by other executables. The auto-generated LibMain is the entry point of the DLL that is called in various instances such as DLL load, DLL unloading, etc. The code there allows you to do different things in each of the cases.
well math.asm assembles for me if I have the stuff uncommented. But test.asm doesnt, it doesn't find the file.
edit:
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: C:\masm32\progs\libs\test.asm
C:\masm32\progs\libs\test.asm(18) : fatal error A1000: cannot open file : C:\mas
m32\progs\math.asm
_
Assembly Error
Press any key to continue . . .
solved this problem. the only problem I have left is that it doesn't find the dll unless it is in the same dir.
Quote from: rotten on April 25, 2009, 10:19:38 PM
solved this problem. the only problem I have left is that it doesn't find the dll unless it is in the same dir.
You have four options:
1. Put it in the same dir (easy)
2. Put it in some dir that is in The Path (ugly)
3. Use a hardcoded full path such \myfolder\mydlls\myfile.dll (works but is not everybody's taste)
4. Use a relative path such as mydlls\myfile.dll (easy and elegant)
Quote from: jj2007 on April 26, 2009, 05:36:31 AM
Quote from: rotten on April 25, 2009, 10:19:38 PM
solved this problem. the only problem I have left is that it doesn't find the dll unless it is in the same dir.
You have four options:
1. Put it in the same dir (easy)
2. Put it in some dir that is in The Path (ugly)
3. Use a hardcoded full path such \myfolder\mydlls\myfile.dll (works but is not everybody's taste)
4. Use a relative pyath such as mydlls\myfile.dll (easy and elegant)
In the same dir works.
Didn't try 2 but 3 and 4 doesn't work. At least importing directly into the file.
Should I somehow pass the dll to the linker if it is not in the same dir?
C:\masm32\progs>\masm32\bin\ml /c /Zd /coff test.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: test.asm
C:\masm32\libs\math\math.dll(1) : error A2044: invalid character in file
C:\masm32\libs\math\math.dll(2) : error A2044: invalid character in file
C:\masm32\libs\math\math.dll(2) : error A2039: line too long
C:\masm32\progs>
; #########################################################################
.386
.model flat, stdcall
option casemap :none
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include C:\masm32\libs\math\math.dll
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib C:\masm32\libs\math\math.lib
; #########################################################################
fac PROTO N : DWORD
fib PROTO N : DWORD
.data
S db "Result is: ", 0
N sdword 5
Acc sdword 0
;IntArray dword 8 dup (?)
.code
start:
invoke fac, 5
invoke fib, 12
utoa:
mov ebx, 10 ; we'll divide by this
xor ecx, ecx ; use as digit-counter
pushloop:
xor edx, edx ;
div ebx ; quotient in eax, remainder in edx
push edx ; store it for later
inc ecx
cmp eax, 0
jnz pushloop
poploop:
pop eax ; get digit back
add al, '0' ; convert to character
mov Acc, eax
push ecx
invoke StdOut, eax ;; addr Acc
pop ecx
loop poploop
ret
;; mov Acc, 1
;; add Acc, 48
;; invoke StdOut, addr Acc
;; invoke StdOut, addr Acc
invoke ExitProcess, 0
end start
Trying to link like this:
C:\masm32\progs>\masm32\bin\Link /DLL /SUBSYSTEM:CONSOLE C:/masm32/libs/math/DEF
:math.def /LIBPATH:c:\masm32\libs test.obj
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
LINK : fatal error LNK1181: cannot open input file "C:/masm32/libs/math/DEF:math
.def"
C:\masm32\progs>
See Dynamic-Link Library Search Order (http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx) for a description of the search order that the system uses to find a DLL. I would use the directory of the application, unless I had a very good reason for doing otherwise.
http://msdn.microsoft.com/en-us/library/ms811694.aspx
;; C:\masm32\progs>\masm32\bin\Link /DLL /SUBSYSTEM:CONSOLE /DEF:C:\masm32\math\mat
;; h.def /LIBPATH:c:\masm32\lib test.obj
is that correct? I get a warning when I assemble but it assembles still and thne it loops forever. I will post ithe error later when I have time.
of course, the modern way of declaring extrnals in a file is much better, but
in the old days we also linked OBJ's together like this...
LINK objfile1.obj+objfile2.obj......
rotten,
Assuming that math.asm is the source for a DLL, why are you including it in the source for test.asm? Math.asm should be separately assembled and linked to produce the DLL and an import library. There are two methods of using the functions in a DLL, see Load-Time Dynamic Linking and Run-Time Dynamic Linking here (http://msdn.microsoft.com/en-us/library/ms681914(VS.85).aspx). The import library is used for Load-Time Dynamic Linking.
math.asm:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.386
.model flat, stdcall
option casemap :none
;----------------------------------------------------
; This is necessary only for the "reason" constants.
;----------------------------------------------------
include \masm32\include\windows.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; -------------------------------------------
; Build this DLL with the provided MAKEIT.BAT
; -------------------------------------------
.data?
hInstance dd ?
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
LibMain proc instance:DWORD,reason:DWORD,unused:DWORD
.if reason == DLL_PROCESS_ATTACH
push instance ; copy local to global
pop hInstance
mov eax, TRUE ; return TRUE so DLL will start
.elseif reason == DLL_PROCESS_DETACH
.elseif reason == DLL_THREAD_ATTACH
.elseif reason == DLL_THREAD_DETACH
.endif
ret
LibMain endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
comment * -----------------------------------------------------
You should add the procedures your DLL requires AFTER
the LibMain procedure. For each procedure that you
wish to EXPORT you must place its name in the "math.def"
file so that the linker will know which procedures to
put in the EXPORT table in the DLL. Use the following
syntax AFTER the LIBRARY name on the 1st line.
LIBRARY math
EXPORTS YourProcName
EXPORTS AnotherProcName
------------------------------------------------------- *
Fac proc N : sdword
mov ecx, N
mov eax, 1
_fac:
mul ecx
loop _fac
ret
Fac endp
;---------------------------
; Modified to preserve EBX.
;---------------------------
Fib proc N : sdword
push ebx
xor eax, eax
mov ebx, 1
mov ecx, N
_fib:
mov edx, eax
add eax, ebx
mov ebx, edx
loop _fib
pop ebx
ret
Fib endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end LibMain
math.def:
LIBRARY math
EXPORTS Fac
EXPORTS Fib
test.asm:
; #########################################################################
.386
.model flat, stdcall
option casemap :none
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
;------------------------------------------------------------
; The includelib directive causes ML to place information in
; the object module that will allow the linker to set up the
; EXE for Load-Time Dynamic Linking. An alternative would be
; to list the libraries on the linker command line.
;------------------------------------------------------------
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
;-----------------------------------------------
; This assumes that the import library math.lib
; is in the current directory.
;-----------------------------------------------
includelib math.lib
;---------------------------------------------------------------
; These prototypes are necessary so MASM will know that Fac and
; Fib are defined in another file (instead of in the current
; file), what name to place in the object module (with the
; STDCALL calling convention the name depends on the size of
; the parameters), and how to invoke the procedures.
;---------------------------------------------------------------
Fac PROTO N:sdword
Fib PROTO N:sdword
; #########################################################################
.data
S db "Result is: ", 0
crlf db 13,10,0
N sdword 5
Acc sdword 0
.code
utoa:
mov ebx, 10 ; we'll divide by this
xor ecx, ecx ; use as digit-counter
pushloop:
xor edx, edx ;
div ebx ; quotient in eax, remainder in edx
push edx ; store it for later
inc ecx
cmp eax, 0
jnz pushloop
poploop:
pop eax ; get digit back
add al, '0' ; convert to character
mov Acc, eax
push ecx
invoke StdOut, addr Acc
pop ecx
loop poploop
ret
start:
invoke Fac, 5
call utoa
invoke StdOut, addr crlf
invoke Fib, 5
call utoa
invoke StdOut, addr crlf
invoke Sleep, 2000 ; delay so output will be visible
invoke ExitProcess, 0
end start
makeit.bat:
: This batch file will first create the DLL and
: import library, and then the test app.
@echo off
if exist mmfdll.obj del math.obj
if exist mmfdll.dll del math.dll
\masm32\bin\ml /c /coff math.asm
pause
\masm32\bin\Link /SUBSYSTEM:CONSOLE /DLL /DEF:math.def math.obj
pause
: This simply lists the files.
dir math.*
pause
\masm32\bin\ml /c /coff test.asm
pause
\masm32\bin\Link /SUBSYSTEM:CONSOLE test.obj
pause
dir test.*
pause