Hello,
Now I'm creating some DLL with masm32. The problem is that I can't create desirable function without mas32 macro. Everything is ok when I use:
DLLFunc proto :DWORD
public DLLFunc
....
DLLFunc proc EXPORT param:DWORD
...
DLLFunc endp
So how can I do it without param and proto? I need to create function with one dword parameter, but i need it to do without macros. If I create function without proto and param I get _DLLFunc@0 in library, but I need _DLLFunc@4. How to do this?
Thanks in advance
alpha
Hi alpha1,
Welcome to the forum.
Did you create a module definition file for your DLL?
You can check Iczelion's Win32asm tutorial #17 about DLLs
Quote from: Vortex on January 23, 2005, 05:46:24 PM
Hi alpha1,
Welcome to the forum.
Did you create a module definition file for your DLL?
You can check Iczelion's Win32asm tutorial #17 about DLLs
Yes, I have create module definition file and I have read Iczelion tutorial, but still I don't understand how to do the same without macros of masm32. By the way, in the example function takes no parameters. My function is with one parameter - DWORD.
alpha
Alpha,
The format of a DLL is very straight forward, create the LibMain or DLLmain entry point and then create any other procedure you like to export. There is a tutorial on the forum web site that will help you write what you are after.
Hello,
Ok I think you don't understand my question becouse of my poor english. I'll try...
So lets look at entrypoint function:
LibMain proc parameter1:DWORD, parameter2:DWORD, parameter3:DWORD
mov eax, TRUE
ret
LibMain endp
The simple question: how to do the same without parameter1:DWORD, parameter2:DWORD.... how to tell masm that this function has 3 parameters without using parameter:DWORD macro? How to do it in old way?
alpha
Maybe you can do it like this. I am not sure if it will work. You also can't use invoke.
LibMain:
push ebp
mov ebp,esp
mov eax,1
leave
ret 12 ; pop off 3 dword args from stack b4 returning (4*3 = 12)
You can access the params at [ebp-08h],[ebp-0Ch],[ebp-10h] etc. But why do so, when you can do it using proc?
Thomas Antony
Alpha,
the problem is the spec for a DLL entry point require 3 x 4 byte parameters on the stack and if it varies from that, it may not run correctly. I have yet to see the point unless its some trivial byte saving example but if you want a DLL to run reliable you must kep that in mind.
You can try something like,
LibMain:
mov eax, 1
ret 12
Quote from: thomasantony on January 24, 2005, 08:49:59 AM
You can access the params at [ebp-08h],[ebp-0Ch],[ebp-10h] etc. But why do so, when you can do it using proc?
:))) Still not good question. Try again:
If I use
Myfunc proc param1:DWORD
...
Myfunc endp
then masm will generate:
push ebp
mov ebp,esp
....
leave
ret 4
and export function will be _Myfunc@4
Now I want to write myself:
Myfunc proc
push ebp
mov ebp, esp
...
leave
ret 4
Now as you can see I do not use any macros, but my export function in dll is _Myfunc@0 but not @4 becouse masm do not know how many parameters there are in the function. How to tell masm about parameters not using param:DWORD???????
Thanks in advance and thanks for patience :)
alpha
Try this one:
Myfunc@4 proc
push ebp
mov ebp, esp
...
Quote from: Vortex on January 24, 2005, 10:43:52 AM
Try this one:
Myfunc@4 proc
push ebp
mov ebp, esp
...
Already tried. Then function in dll is _myfunc@4@0 :( thats why i'm asking :/
alpha
Alpha,
Perhaps I dids not connect the problem you are creating with what you are after. A DLL entry point is defined by the OS so you get it right or it does not work. What I suggested to you was to,
1. Return non zero in EAX so the DLL will run.
2. Use the RET 12 to balance the stack
You have still not made sense of what you are trying to do and why you are trying it.
Quote from: hutch-- on January 24, 2005, 01:40:02 PM
You have still not made sense of what you are trying to do and why you are trying it.
Never mind... It's too hard for me to explain in english. I tried to explain it with asm code, but I didn't suceed. Thanks anyway
alpha
It sounds to me like he wants to get the correct name mangling of his function.
If he uses a macro, MASM correctly interprets his function as taking said parameters and generates a manged name with @4, at the end.
If he does not use the masm macro, the linker does not correctly mangle his procedures name.
He does not have any questions as to how to create a procedure or a DLL, he simply wonders why the linker mangles his name differently for seemingly exact code.
Linkers use name mangling as we should all know to differentiate between overloaded functions. Thus, in your c program, the functions:
void myFunc(int)
is name mangled to be something different than
void myFunc(float)
Apparently, the linker is not recognizing his code as taking the correct number of parameters.
I would take a stab in the dark and guess that the proc macro also defines a function prototype, therefore allowing the linker to correctly identify the number of parameters that it takes.
So maybe that is a suggestion, declare the prototype of your function with PROTO
alpha1,
If I understood correctly the situation, this might help you:
DLL source code:
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
public StdOut@4
.code
DllEntry:
mov eax,TRUE
ret 12
StdOut@4: ;StdOut function from masm32.lib
push ebp
mov ebp,esp
add esp,-12 ;3 dwords
; LOCAL hOutPut :DWORD
; LOCAL bWritten :DWORD
; LOCAL sl :DWORD
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov [ebp-4], eax ; hOutPut
invoke lstrlen,[ebp+8] ; lpszText
mov [ebp-12], eax
lea eax,[ebp-8] ; bWritten
invoke WriteFile,[ebp-4],[ebp+8],[ebp-12],eax,NULL ; [ebp-12] = sl
mov eax,[ebp-8]
leave
ret 4
END DllEntry
Sample code using this DLL:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib Console.lib
includelib \masm32\lib\kernel32.lib
StdOut PROTO :DWORD
.data
msg db 'Hello my friend!',0
.code
start:
invoke StdOut,ADDR msg
invoke ExitProcess,0
END start
You can check the attachment to see how to build the DLL and the sample code.
[attachment deleted by admin]
Quote from: Vortex on January 24, 2005, 06:39:53 PM
You can check the attachment to see how to build the DLL and the sample code.
Finally two last posters seems to understood my question. I'm sorry for my english again :)
So the last example has worked just fine for me, but before that I have discovered, that I have problems when I use:
.model 386p, stdcall but everything is ok when I use
.model 386p
Now I'm lost completely. You use .model 386p, stdcall in your example and program works just fine?? The only difference is thatr I'm using .model without stdcall key, I do not use casemap option and I use:
myfunc proc:
myfunc endp
you use only myfunc:
So I just don't see the difference. I'll try to look more deeply. Thanks for your answers !
alpha
sorry not
.model 386p, stdcall but
.model FLAT, stdcall
:red
alpha
Yes, I was wrong. .model FLAT, stdcall was the key for all this madness :) But I still prefer not using stdcall key in /model definition. It is becouse I can use different calling convention functions in the same library.
Thanks again.
alpha
You can do that anyway by making individual prototypes with differenct calling conventiona. Almost all API calls are STDCALL by wsprintfA is C.
Hi alpha1,
QuoteI can use different calling convention functions in the same library
What are the conventions you are using?
Hi alpha1,
proc is a MASM keyword that make a stack frame using push ebp, mov ebp,esp etc. If you do not want to use it, declare your proc as a label like Vorte did and implement all the stack stuff yourself!!
Thomas Antony
Quote from: Vortex on January 25, 2005, 10:39:29 AM
What are the conventions you are using?
Mostly stdcall and cdecl.
alpha
Hi alpha1,
Why don't you prefer using PROC & ENDP statements to code your procedures?
Alpha1,
A label in assembler is a meaningful name the compiler uses to "mark" an offset in the code.
A function like "myFunction:" just marks an entry point to some instructions and makes it easy for us to read the code.
When you dont use the macros for defining the function you need to ensure that the instructions following the
label contain the right prologue and cleanup for a function. ie: pushing arguments onto the stack and balancing them
afterward. If you use the macro this is done for you.
When you export a function using the export keyword or a definition file you are just making the label externally available.
When you jmp to a label execution moves from the current place in the code to the label.
Different calling conventions will influence how the stack is treated when the ret instruction is encountered.
You can do away with any calling convention macro, but you will still need to do these things manually.
If you want 'c' calling convention then you will have to push the parameters onto the stack in the right 'c' order and
balance the stack yourself. If you use a different calling convention then different rules apply.
Some of this is more clear in the documentation for goASM as it has less macros and there is a great section in the
help about labels and using them. Even making nested procs with labels etc. This may help you.
I admire your desire to fund a low level way to implement functions. Like the way you would do it is macros didnt exist
at all. That one of the reasons I used and like goASM. However, the same is achievable in MASM.
I hope this helps.