News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

using dumpbin.exe to create a .def file

Started by MikeT, October 09, 2009, 09:46:06 AM

Previous topic - Next topic

hutch--

Mike,

The trailing number is the bytecount for the arguments passed to the function. When you see,


  _MessageBoxA@16


It has 16 bytes of arguments. This info is for the linker to check the arguments.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MikeT

Aaaah so its not decoration at all then. Great!
So if I have four arguments that are 4Byte LONG integers for example the byte count would be 16.
If I have four 8Byte DOUBLE's then the byte count would be 32 correct?

So I can write a program to automate this after all.
All I need is a way to list the arguments of the functions from the Dll itself.
dumpbin options
http://support.microsoft.com/kb/177429
don't seem to cover this.

There must be a way do it and get the byte count. Possibly from the PE header perhaps?

If not I will have to go through every exported function and count the bytes by hand. Urgh I hope not. I think I would rather use the CDECL calling convention.
How many additional clock cycles is the CDECL function call over the STDCALL?



Vortex

Hi MikeT,

You are right with the byte calculation. I already explained it here

It's possible to write a tool creating def files from Power Basic source code files. I am not a PB user but I see that the symbol ' means comment.

' ##AddTwoNum=12

A tool scanning the PB source code should interpret the line above like the following :

- A line with the leading ' symbol is a commented line
- The double # symbols means that the following word ( here AddTwoNumb ) should be copied to the destination def file.
- Finally =12 should be translated as @12

The output :


"_AddTwoNum@12"


Naturaly, you can find better methods to extract def files from PB code. My proposal above is a simple example.

A more advanced tool can convert the following code :

FUNCTION AddTwoNum SDECL ALIAS "AddTwoNum" ( BYVAL k    AS LONG , _
                                             BYVAL mpg  AS DOUBLE ) EXPORT AS LONG
    MSGBOX "k="+STR$(k) + ", mpg="+STR$(mpg),64,"DLL Values Received:"
  FUNCTION = k + CLNG(mpg)
END FUNCTION


to the simple entry :


"_AddTwoNum@12"

MikeT

#33
Oh now I feel like an idiot. I thought that explanation was describing decoration because I had it in my head that the @ sign indicated decoration. In the last 10mins I have finally understood this is the number of bytes for the stack and forgot your detailed explanation. Thank you for your patience. This is clearly a case of not being able to see the wood for the trees.

I think I have a PB code parser fro another tool I wrote years ago that finds un-used variables and deletes them in source code. I am sure it could be adjusted to serve. Thank you again.

hutch--

Mike,

I have heard of the dumpbin method but years ago it was not very good and there are far better ways of doing it. Vortex has explained what is probably the best way to do this with Pelle's tools. For what its worth you don't have to have the trailing byte count to make a library. Also note that it is not optional to change the calling convention unless you feel like rewriting all of your PowerBASIC source code to C and getting it to work properly.

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MikeT

>you don't have to have the trailing byte count to make a library.
If its CDECL you are correct. But if its STDCALL you do need the byte count or the VS2008 linker will choke. Thats the rub.

>it is not optional to change the calling convention unless you feel like rewriting all of your PowerBASIC source code
Well I could simply insert CDECL before the function definitions in my PB code and then re-compile the DLLs.
The problem with that is that the C calling convention executes code that performs stack cleanup etc each tiem the function is called (STDCALL does not, hence the need for the byte count I assume)
I am wondering what the overhead for that is in Clocks?

hutch--

Its the other way around, STDCALL balances the stack but is limited to fixed and known argument count, C can use variable argument count but the CALLER must balance the stack. I suggest you will have to use tools from the after market to make the libraries you want, its easy to do in MASM but you have to know how to use MASM It builds its own libraries on installation so its no big deal.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

For the C calling convention the stack cleanup is just an:

add esp, N

So the overhead is minimal, and there is at least a possibility that eliminating the constant operand (that specifies the number of bytes to release) from the RET instruction would speed it up enough to compensate.


eschew obfuscation

MikeT

Hmmm that's not what I read here:
http://books.google.com/books?id=4VOKcEAPPO0C&pg=PA134&lpg=PA134&dq=cdecl+fastest+convention&source=bl&ots=WC3pL5wv5X&sig=Mr5ijgMgXFm5kohI9uSQpKMwBA0&hl=en&ei=15zRSuuiBJDgtgOC8f3vCw&sa=X&oi=book_result&ct=result&resnum=3&ved=0CBEQ6AEwAg#v=onepage&q=cdecl%20fastest%20convention&f=false
http://www.tantalon.com/pete/cppopt/compiler.htm

I am not worried about this tho:
"Having the caller being responsible for cleanup the stack gives slightly bigger programs since the stack maintenance code is now at many places whereas it"
http://www.ng-sw.de/mg-wikka/CallingConventions

But I trust you ASm guys more of course for obvious reasons. If you say CDECL is faster than STDCALL then I will simply compile all my Dlls using that calling convention and make a simple parser to create the .def file. Thats easier anyway.

BlackVortex

Don't worry about the speed difference of different calling conventions ... it's negligible for normal purposes.

MichaelW

In my test, running on a P3, the C calling convention is slightly faster, but 3 cycles in 30 calls is a less than negligible difference.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    .686
    include \masm32\macros\timers.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
ProcStdcall proc arg1:DWORD, arg2:DWORD
    ret
ProcStdcall endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
ProcC proc C arg1:DWORD, arg2:DWORD
    ret
ProcC endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke Sleep, 4000
    counter_begin 1000, HIGH_PRIORITY_CLASS
        REPEAT 30
            invoke ProcStdcall, 1, 2
        ENDM
    counter_end
    print ustr$(eax)," cycles, STDCALL",13,10

    counter_begin 1000, HIGH_PRIORITY_CLASS
        REPEAT 30
            invoke ProcC, 1, 2
        ENDM
    counter_end
    print ustr$(eax)," cycles, CDECL",13,10,13,10

    inkey "Press any key to exit..."
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


294 cycles, STDCALL
291 cycles, CDECL

eschew obfuscation

MikeT

Perfect!
That settles that then. I'll just use CDECL convention for all my PB Dll's.

This has completed a weeks work! Thank you all. I began last Saturday in an attempt to do a demonstration of the FastCGI library
http://www.coastrd.com/cheader
in C++ but ran into all these issues in VS2008 C++ compiler/linker.

The stdcall example has illuminated why cdecl is a more universal format.

hutch--

Here are the results on my quad.


179 cycles, STDCALL
187 cycles, CDECL

Press any key to exit...


The amount of messing around to convert PB code to C convention is a waste of effort unless you have time to waste. There is effectively no performace difference for anything except the shortest of procedures.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MikeT

Well I have to refactor my PB dll code either by figuring put the byte count when calling stdcall, or by inserting one word "CDECL" in the function declaration. Since the subsequent steps can be automated if I use CDECL I might as well make my like easy and go that route. Also the chance of making a mistake if I try to hand code many functions in the .def file is quite high.

MikeT

http://www.winasm.net/forum/index.php?showtopic=97
"I used sometimes wsprintf without any type of stack-cleaning (as i saw in many examples) and the function works correctly"
Didnt know that.