What will be the calling convention if the .model directive doesn't specify a langtype?
This is related to my previous question here:
http://www.masm32.com/board/index.php?topic=16798.0
Here is the asm generated by my compiler. The .model directive doesn't have any langtype given. The proc name is already decorated by the C++ compiler:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01
TITLE C:\work\vc2008\asm\asm\proc1.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRT
INCLUDELIB OLDNAMES
PUBLIC ?add_10@@YAHH@Z ; add_10
; Function compile flags: /Ogtp
; File c:\work\vc2008\asm\asm\proc1.cpp
; COMDAT ?add_10@@YAHH@Z
_TEXT SEGMENT
_retVal$ = -4 ; size = 4
_arg1$ = 8 ; size = 4
?add_10@@YAHH@Z PROC ; add_10, COMDAT
; 8 : {
push ebp
mov ebp, esp
push ecx
:
:
mov esp, ebp
pop ebp
ret 0
?add_10@@YAHH@Z ENDP ; add_10
_TEXT ENDS
END
I directly assembled it with masm v10, and got a .obj file with these info (extracted by dumpbin.exe):
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file proc1.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 009E766F ABS notype Static | @comp.id
001 00000000 SECT1 notype Static | .text
Section length 19, #relocs 0, #linenums 0, checksum 0
003 00000000 SECT2 notype Static | .data
Section length 0, #relocs 0, #linenums 0, checksum 0
005 00000000 SECT3 notype Static | .debug$S
Section length 78, #relocs 0, #linenums 0, checksum 0
007 00000000 SECT4 notype Static | .drectve
Section length 28, #relocs 0, #linenums 0, checksum 0
009 00000000 SECT1 notype () External | ?add_10@@YAHH@Z (int __cdecl add_10(int))
String Table Size = 0x14 bytes
Summary
0 .data
78 .debug$S
28 .drectve
19 .text
It gave me an undecorated proc name. It seems like ML didn't further decorate the name (which is what I want but linker still cannot resolve the name).
But what calling convention is it using?
Note that when I changed the .model to C or stdcall, the proc name were decorated accordingly. So, omitting the langtype in .model isn't the same as using either C or stdcall as the default. What should I expect now?
I list the results for C and stdcall here:
.model flat, C
the dumpbin gave me this:
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file proc1.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 009E766F ABS notype Static | @comp.id
001 00000000 SECT1 notype Static | .text
Section length 19, #relocs 0, #linenums 0, checksum 0
003 00000000 SECT2 notype Static | .data
Section length 0, #relocs 0, #linenums 0, checksum 0
005 00000000 SECT3 notype Static | .debug$S
Section length 78, #relocs 0, #linenums 0, checksum 0
007 00000000 SECT4 notype Static | .drectve
Section length 28, #relocs 0, #linenums 0, checksum 0
009 00000000 SECT1 notype () External | _?add_10@@YAHH@Z
String Table Size = 0x15 bytes
Summary
0 .data
78 .debug$S
28 .drectve
19 .text
and
.model flat ,stdcall
dumpbin gave me this:
007 00000000 SECT4 notype Static | .drectve
Section length 28, #relocs 0, #linenums 0, checksum 0
009 00000000 SECT1 notype () External | _?add_10@@YAHH@Z@0
String Table Size = 0x17 bytes
i can't find the default calling convention for the flat model (it may be the same for all models)
but - it should be easy enough to figure out
write a routine that requires 2 parameters from INVOKE
from the listing or by using olly...
1) test the order that the parameters are pushed
2) test to see if the RET balances the stack
from those 2 results, you should be able to determine the default convention
stdcall, syscall, fastcall, c, pascal, basic - i may have forgotten a couple :P
EDIT - it looks like the casemap is a 3rd test
i tried pascal, and it wanted all the function names to be all capital letters :bg
But, is there anyone that doesn't do any name decoration? I don't know about PASCAL, BASIC, FASTCALL & SYSCALL. I just feel that the dumpbin output does not look right. There isn't any name decoration at all.
I am suspecting that omitting the langtype in .model directive will disable name decoration but cannot find any MASM documentation mentioning it. Not even in MSDN.
This example shows that the proc name is manually decorated when called by C and the langtype is not required:
http://praseedp.blogspot.com/2010/07/using-32-bit-masm-with-visual-c.html
I am sure if that e.x. adds C langtype after .model, it cannot link with the C module.
Default language is SYSCALL. You can specify
extern "C" before a c++ function to make it use simple c decoration.
QuoteIt seems like ML didn't further decorate the name (which is what I want but linker still cannot resolve the name).
Resolve where? Where is it referenced and how?
What does SYSCALL involve?
Is it no decoration, parameter passing and cleaning = _cdecl, and case sensitive name?
Same as C but without the underscore.
- Programmer's Guide
http://web.sau.edu/lilliskevinm/csci240/masmdocs/
Ch. 12 - Mixed-Language Programming
http://web.sau.edu/lilliskevinm/csci240/masmdocs/programmersguide/16LMAPGC12.pdf
Table 12.1 Naming and Calling Conventions
[/list]
[/list]
Hi msqweasm,
You can turn off the name decoration with the usage of the SYSCALL calling convention :
- The _invoke macro replaces the normal invoke macro to avoid the stack balancing forced by the SYSCALL convention.
- No need of function prototypes but you have to declare the API functions :
extern ExitProcess:PROC
extern GetCommandLineA:PROC
GetCommandLine equ <GetCommandLineA>
.
.
- You must take care of stack balancing inside procedures :
WndProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg==WM_DESTROY
_invoke PostQuitMessage,NULL
.ELSE
_invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret 4*4
.ENDIF
xor eax,eax
ret 4*4
WndProc ENDP
The ret 4*4 instructions are balancing the stack manually.
Building the sample project :
\masm32\bin\polib /OUT:kernel32.lib /NOUND C:\WINDOWS\system32\kernel32.dll
\masm32\bin\polib /OUT:user32.lib /NOUND C:\WINDOWS\system32\user32.dll
\masm32\bin\ml /c /coff Window.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS Window.obj kernel32.lib user32.lib
\goasm\golink /fo Window2.exe Window.obj kernel32.dll user32.dll
Pelle's Polib, the library manager builds the undecorated import libraries ( the /NOUND switch )
If you don't wish to build and use those import libraries, Jeremy Gordon's linker Golink creates a second executable named Window2.exe
Thanks for all the very helpful advices.
Another question, where is the _invoke macro defined? I can't find in it the masm32 distribution.
The _invoke macro is defined in the file window.inc in the attachment that Vortex posted.
Hi msqweasm,
You can easily replace the _invoke macro with consecutive push statements.
_invoke DefWindowProc,hWnd,uMsg,wParam,lParam
can be converted to :
push lParam
push wParam
push uMsg
push hWnd
call DefWindowProc
Hi Hi msqweasm,
You can remove the language type from the .model directive but you have to modify the source code :
.386
.model flat
option casemap:none
As we have a bare .model statement above, you need to move the language type statement to the definition of the procedures :
WinMain PROC SYSCALL hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
Finally, I copied the necessary structure definitions and equates to Window.inc to avoid some error messages while assembling the code :
\masm32\include\windows.inc(60) : error A2119: language type must be specified