NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: ben321 on October 18, 2015, 05:06:37 AM
-
I was looking at this sample code
GLOBAL DllMain
EXPORT DllMain
GLOBAL myFuncX1
EXPORT myFuncX1
GLOBAL myFuncX2
EXPORT myFuncX2
section .code use32
..start:
DllMain: ; This code is required in .dll files
mov eax,1
ret 12
myFuncX1:
; FUNCTION #1
; A- passed parameters:
; required: value#1 , value#2
;
; example:
; push dword [0x500]
; push dword [0x010]
; call [myFuncX1]
;
; B- this function returns:
; EAX= value#1 + value#2
push ebp
mov ebp, esp
mov eax, dword [ebp+08] ; eax=value#1
mov ecx, dword [ebp+12] ; ecx=value#2
.
.
.
.
.
etc
(this is a truncated copy of the sample code found at http://forum.nasm.us/index.php?topic=1652.0 )
I was wondering a few things.
On the entry point for DllMain I notice that not only is it set to GLOBAL like the entrypoint function in EXE files, but also it is exported. Does the entrypoint function in a DLL file really need to be exported? What if it's not going to be called from another program?
I then noticed something else. Other functions like myFuncX1 and myFuncX2 that are going to be exported not only have the compiler directive EXPORT, but they also use GLOBAL. Isn't GLOBAL only required on an entrypoint function? And I also noticed the exact structure of the entrypoint function. It contains the code:
mov eax,1
ret 12
This leaves me with 2 questions.
1) Why does it need to set EAX (the register that holds the return-value of a function) to 1? If you aren't going to be using the entrypoint function in your programming, do you really need to set EAX to a specific value?
2) Why is "ret 12" needed? Having a number after the "ret" opcode is only needed if you need to skip a specific number of bytes in the stack when returning. I don't think there's anything on the stack, unless your function put something there. In EXE files, I've been able to use just "ret" without any number. Why is it needed for DLL files?
-
This leaves me with 2 questions.
1) Why does it need to set EAX (the register that holds the return-value of a function) to 1? If you aren't going to be using the entrypoint function in your programming, do you really need to set EAX to a specific value?
2) Why is "ret 12" needed? Having a number after the "ret" opcode is only needed if you need to skip a specific number of bytes in the stack when returning. I don't think there's anything on the stack, unless your function put something there. In EXE files, I've been able to use just "ret" without any number. Why is it needed for DLL files?
The answer to all of your questions can be found here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx)
-
This leaves me with 2 questions.
1) Why does it need to set EAX (the register that holds the return-value of a function) to 1? If you aren't going to be using the entrypoint function in your programming, do you really need to set EAX to a specific value?
2) Why is "ret 12" needed? Having a number after the "ret" opcode is only needed if you need to skip a specific number of bytes in the stack when returning. I don't think there's anything on the stack, unless your function put something there. In EXE files, I've been able to use just "ret" without any number. Why is it needed for DLL files?
The answer to all of your questions can be found here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx)
Thanks, but that only answered my last 2 questions. I still have these questions, which have so far gone unanswered.
On the entry point for DllMain I notice that not only is it set to GLOBAL like the entrypoint function in EXE files, but also it is exported. Does the entrypoint function in a DLL file really need to be exported? What if it's not going to be called from another program?
Also, the other functions like myFuncX1 and myFuncX2 that are going to be exported not only have the compiler directive EXPORT, but they also use GLOBAL. Isn't GLOBAL only required on an entrypoint function?
-
Some of my questions are still unanswered. Somebody, please answer them. I need to know these things before I proceed with trying to make a DLL file.
-
Does the entrypoint function in a DLL file really need to be exported? What if it's not going to be called from another program?
I guess it it isn't going to be called from another program, it doesn't matter.
Also, the other functions like myFuncX1 and myFuncX2 that are going to be exported not only have the compiler directive EXPORT, but they also use GLOBAL. Isn't GLOBAL only required on an entrypoint function?
No, that is not correct.
Essentially, "global" says "tell the linker that this symbol can be found in this file." (it can be a function, or data)
"extern" says "ask the linker where this symbol can be found. It isn't in this file." (presumably declared "global" someplace else)
Per the Nasm Manual...
Extern: http://www.nasm.us/doc/nasmdoc6.html#section-6.5
Global: http://www.nasm.us/doc/nasmdoc6.html#section-6.6
Import and Export are specific to the "-f obj" (OMF) output format.
The content and usage of a DLL file are questions best put to Microsoft, as Rob suggests, although Wikipedia has some info on 'em: https://en.wikipedia.org/wiki/Dynamic-link_library
Best,
Frank
-
Does the entrypoint function in a DLL file really need to be exported? What if it's not going to be called from another program?
I guess it it isn't going to be called from another program, it doesn't matter.
Also, the other functions like myFuncX1 and myFuncX2 that are going to be exported not only have the compiler directive EXPORT, but they also use GLOBAL. Isn't GLOBAL only required on an entrypoint function?
No, that is not correct.
Essentially, "global" says "tell the linker that this symbol can be found in this file." (it can be a function, or data)
"extern" says "ask the linker where this symbol can be found. It isn't in this file." (presumably declared "global" someplace else)
Per the Nasm Manual...
Extern: http://www.nasm.us/doc/nasmdoc6.html#section-6.5
Global: http://www.nasm.us/doc/nasmdoc6.html#section-6.6
Import and Export are specific to the "-f obj" (OMF) output format.
The content and usage of a DLL file are questions best put to Microsoft, as Rob suggests, although Wikipedia has some info on 'em: https://en.wikipedia.org/wiki/Dynamic-link_library
Best,
Frank
I have found that while Import doesn't work "-f win32", and will only work if i use "-f obj", Export does work with "-f win32" and is in fact required for exporting a function from a DLL file that is being assembled with NASM. Using GLOBAL by itself isn't sufficient to set up a function to be exported. In fact, if I use EXPORT, and don't even use GLOBAL at all, it automatically makes the DLL function you are trying to export be successfully exported (such that an EXE file compiled using EXTERN will be able to find the function, when using a linker like GoLink which can take the name of the DLL file itself as a parameter, to get around needing to use IMPORT in NASM, which doesn't work when using "-f win32" mode). So you really only need GLOBAL (without EXPORT) on the DLL entrypoint function and you only need EXPORT (and not GLOBAL) on any functions that you want to call from another program. It seems as if the EXPORT command in NASM performs the 2 separate commands GLOBAL and EXPORT, which might have to be used as 2 separate commands in other assemblers. Not sure if this is technically the correct way to do it, but it seems to work perfectly fine in the experiments I've done with it.
Also, you mention that "I guess it it isn't going to be called from another program, it doesn't matter." referring to the use of EXPORT on the entrypoint function. However the entrypoint function is supposed to automatically run (this is done by the Windows OS I think, rather than the program that is to be using the DLL file) whenever a DLL is loaded by a program that will be using it. Does Windows OS itself have its own way of running the main function of a DLL file, without it being exported? Does the fact that this function is at the DLL's entry point make a difference?