Here is a GNU Assembler example. It's created with as.exe and ld.exe coming with MinGW - Minimalist GNU for Windows.
Thanks to baldr for his GAS invoke macro.
.intel_syntax noprefix
.global _start
.include "invoke.inc"
.include "Dlgbox.inc"
.data
DlgName:
.asciz "MyDialog"
.bss
hInstance:
.long 0
hCursor:
.long 0
.text
_start:
invoke GetModuleHandle,0
mov hInstance,eax
invoke DialogBoxParam,hInstance,"OFFSET DlgName",0,"OFFSET DlgProc",0
invoke ExitProcess,eax
// DlgProc PROC hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
DlgProc:
push ebp
mov ebp,esp
cmp dword ptr [ebp+uMsg], WM_CLOSE
jne initdlg
invoke EndDialog,[ebp+hWnd],0
jmp true
initdlg:
cmp dword ptr [ebp+uMsg], WM_INITDIALOG
jne setcursor
invoke LoadCursor,0,IDC_CROSS
mov hCursor,eax
jmp true
setcursor:
cmp dword ptr [ebp+uMsg], WM_SETCURSOR
jne false
invoke SetCursor,hCursor
jmp true
false:
xor eax,eax
pop ebp
ret 4*4
true:
mov eax,1
pop ebp
ret 4*4
// DlgProc ENDP
// END start
Building the project :
set PATH=%PATH%;E:\MinGW\bin;E:\MinGW\msys\1.0\bin
windres Rsrc.rc Rsrc.o
as -o Dlgbox.o Dlgbox.asm
ld -e _start -subsystem windows -o Dlgbox.exe Dlgbox.o Rsrc.o -lkernel32 -luser32 -s
EDIT : Removed the unnecessary parameter -LE:\MinGW\lib from ld.exe
hi Vortex,
solid work. :t
The source code is similar to the masm source code. It seems that gas performs well.
Gunther
Hi Gunther,
Masm is better as it's macro engine is much more poweful.
Hi Vortex,
Quote from: Vortex on December 23, 2012, 11:57:13 PM
Masm is better as it's macro engine is much more poweful.
no doubts about that. But it's interesting that we've now an invoke macro for gas.
Gunther
Hi Gunther,
The author of the macro is a member of the Asm community forum. Another member of the forum, theorizer wrote the macro below :
.altmacro
.macro ccall func:req, arg1, args:vararg
local argc
argc = 0
/* recursive reverse pusher */
.macro pusher parg1, pargs:vararg
.ifnb \parg1
pusher \pargs
push \parg1
argc = argc + 1
.endif
.endm
pusher \arg1 \args
call \func
/* check if there were arguments pushed */
.if \argc
add esp, argc * 4
.endif
.endm
Attached is an example of Masm object file linking with GNU linker ld.exe
set PATH=%PATH%;E:\MinGW\bin;E:\MinGW\msys\1.0\bin
\masm32\bin\ml /c /coff *.asm
ld -e _WinMainCRTStartup -subsystem windows -o SimpleWnd.exe SimpleWnd.obj crt0gui.obj -lkernel32 -luser32 -s
Hi Vortex,
Quote from: Vortex on December 24, 2012, 01:50:28 AM
The author of the macro is a member of the Asm community forum. Another member of the forum, theorizer wrote the macro below :
why not. There are of course qualified assembly language programmers in that forum.
Gunther
I posted a pair of macros somewhere in the 2008-2009 range. They are not as compact as these later ones, and may assemble somewhat slower. AFAIK this is the original code, but with expanded comments.
//.intel_syntax noprefix
//.altmacro
/*
; For irp the statements are assembled at least once, so in
; the ifnc blocks that count the arguments detecting a
; no-args condition requires a check for a null argument.
;
; The clumsy double-loop arrangement is the only compact and
; flexible method that I could find to push the arguments in
; right to left order.
;
; These macros are coded to minimize the number of loops (an
; exitm directive in a loop exits the innermost loop only).
;
; These macros work correctly with no optional arguments.
;
; The cinvoke macro assumes 32-bit arguments. Byte or word
; arguments can be passed by zero or sign extending them
; into a 32-bit register and passing the register. Qword
; arguments can be passed as two dword arguments, with the
; low-order dword on the left and the high-order dword on
; the right, as they appear in the cinvoke statement.
;
; Because the cinvoke macro calls the invoke macro, certain
; types of errors in the cinvoke macro arguments will cause
; errors to be reported for both macros.
*/
.macro invoke, func:req, args:vararg
n=0
.irp arg,\args
.ifnc \arg,
n=n+1
.endif
.endr
.if n>0
i=n
.irp junk,\args
j=0
.irp arg,\args
j=j+1
.if j==i
push arg
.exitm
.endif
.endr
i=i-1
.endr
.endif
call \func
.endm
.macro cinvoke, func:req, args:vararg
n=0
.irp arg,\args
.ifnc \arg,
n=n+1
.endif
.endr
invoke \func, \args
.if n>0
add esp, n*4
.endif
.endm
IIRC I was able to use these macros in FreeBASIC inline assembly.
Also, the minimum workable version of as for these macros is somewhere between 2.15.94 and 2.18.50.
Hi MichaelW,
Thanks for the macro.
Trying your version of invoke on the example I posted above, I got the error messages below :
Dlgbox.o:fake:(.text+0x2): undefined reference to `arg'
Dlgbox.o:fake:(.text+0x12): undefined reference to `arg'
Dlgbox.o:fake:(.text+0x18): undefined reference to `arg'
Dlgbox.o:fake:(.text+0x1e): undefined reference to `arg'
Dlgbox.o:fake:(.text+0x24): undefined reference to `arg'
Dlgbox.o:fake:(.text+0x2a): more undefined references to `arg' follow
I added a slash \ symbol to the push statement and this solved the problem :
Modifying from :
.if j==i
push arg
.exitm
.endif
to :
.if j==i
push \arg
.exitm
.endif
Tools : binutils-2.23.1 dating 15 November 2012
MichaelW, I tried to split the long line below but it didn't work for me :
invoke DialogBoxParam,hInstance,"OFFSET DlgName",0,"OFFSET DlgProc",0
invoke DialogBoxParam,\
hInstance,\
"OFFSET DlgName",\
0,"OFFSET DlgProc",0
Dlgbox.asm: Assembler messages:
Dlgbox.asm:27: Warning: stray `\'
Dlgbox.asm:27: Warning: stray `\'
Dlgbox.asm:27: Warning: stray `\'
Dlgbox.asm:27: Warning: stray `\'
Dlgbox.asm:27: Warning: stray `\'
Dlgbox.asm:27: Warning: stray `\'
Dlgbox.asm:27: Error: invalid character '\' before operand 1
Dlgbox.asm:28: Warning: stray `\'
Dlgbox.asm:28: Error: invalid character ',' in mnemonic
Dlgbox.asm:29: Error: junk at end of line, first unrecognized character is `"'
Dlgbox.asm:30: Error: junk at end of line, first unrecognized character is `0'
How can I break the line into multiple lines in GAS?
Hi Vortex,
My macros require the
.altmacro directive (http://sourceware.org/binutils/docs-2.23.1/as/Altmacro.html#Altmacro). Sorry, I should have stated this. I commented it out in the macro source because I normally include it in the assembly source.
For the line continuation problem I found this:
http://linuxvm.org/present/SHARE99/S8131db.pdf
Quote
GAS is free-form. Continuation is indicated by ending a line with a backslash (\), just like C.
But it does not seem to work with my macros.
Hi MichaelW,
Many thanks for the information and the link. Your macro works fine without the .altmacro statement. The backslash symbol didn't work for me too.
Some links :
Installing MinGW on Windows (http://kemovitra.blogspot.com/2012/11/installing-mingw-on-windows.html)
How to install MinGW, MSYS and Eclipse on windows (http://www.multigesture.net/articles/how-to-install-mingw-msys-and-eclipse-on-windows)
IDE for MinGW : Code::Blocks Portable
http://portableapps.com/node/18671
For those who would like to use latest versions of as.exe and ld.exe from the Cygwin package, the dependencies are the following :
cygwin1.dll
cygiconv-2.dll
cygintl-8.dll
Hi Vortex,
Quote from: Vortex on December 29, 2012, 09:00:09 PM
Some links :
Installing MinGW on Windows (http://kemovitra.blogspot.com/2012/11/installing-mingw-on-windows.html)
MinGW is a solid tool. I'm working with it since many years and it has the same behaviour like the original gcc.
Gunther
Same example linked with Polink.exe :
\masm32\bin\polink /SUBSYSTEM:WINDOWS /ENTRY:start /LIBPATH:\masm32\lib Dlgbox.o Rsrc.o kernel32.lib user32.lib
GUI example coded by MichaelW :
https://www.freebasic.net/forum/viewtopic.php?f=6&t=10432&start=15
Attached is project built with GNU Binutils 2.28