The MASM Forum
General => The Workshop => Topic started by: Vortex on December 23, 2012, 11:25:27 PM
-
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,
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,
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
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,
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