well not quite:
these two macros are really overlays of the library and import macros
but they are easier to type and they allow a new sintax for invoking
imported functions:
the first macro is called 'librarys' and it takes as parameters the list
of dll from which you want to import the functions,they must be typed
exactly as the name of the dll but without the quotes an the '.dll'
like:
librarys kernel32,msvcrt,user32
the second macro is called 'from' and it takes first the name of the dll(same as it was
declared in the above macro) and pairs of arguments: the first one is the name of the
function (exactly as exported by the dll) and the second one of the symbols:
std or c to specify the calling convention:
from msvcrt,printf,c
from kernel32,ExitProcess,std\ ,GetCommandLineA,std
from user32,MessageBoxA,std\
,MessageBoxW,std
the names of the functions are defined as labels in the import section
but they will get also defined as macros.
macros that just call the invoke or cinvoke macros(acording to the std or c specification
that was made in the 'from' macro)passing the parameters that are passed to them.
these macros are defined to take only one parameter, that is why they must be used with < and > like:
printf<FormatString,arg>
MessageBoxW<0,message,title2,0>
these macros won't interfere with the invoke or cinvoke macros,you can mix the calls
in the same sorce like:
invoke MessageBoxA,0,mes1,title1,MB_OK
MessageBoxW<0,mes2,title2,0>
there is only 2 things:
1.
if you use the extended header (win32ax) and you want to use the capability
to invoke functions inside other functios you must use invoke or cinvoke.
MessageBoxA<0,<invoke GetCommandLineA>,title1,MB_OK>
although there is a defined macro GetCommandLineA that you can use simply typing:
it won't work inside other macro,that is why you must use invoke.
2.
since macros can't be forward referenced the import data or import section must be placed
at the very beginning of the source.
the source for the macros:
lib_list equ
macro append item
{
match any,lib_list\{ lib_list equ lib_list,item\}
match ,lib_list \{ lib_list equ item\}
}
macro librarys [lib_names]
{
append lib_names
append `lib_names#'.dll'
common
match params, lib_list \{library params\}
lib_list equ
}
macro make_stdmac name
{
macro name args
\{
invoke name,args
\}
}
macro make_cmac name
{
macro name args
\{
cinvoke name,args
\} ;_#name
}
macro from dllname,[function,conv]
{
common
append dllname
forward
append function
;_#function
append `function
common
match params, lib_list \{import params\}
lib_list equ
;------------------------------
forward
match =std,conv
\{
make_stdmac function
\}
;------------------------------
match =c,conv
\{
make_cmac function
\}
;------------------------------
}
if you save that source to a file 'libs.inc' here is a translation to the new syntax
of the beer example:
; Beer - example of tiny (one section) Win32 program
format PE GUI 4.0
include 'win32a.inc'
include 'libs.inc'
; no section defined - fasm will automatically create .flat section for both
; code and data, and set entry point at the beginning of this section
entry start ;since we put import data at the beginning
;we must specify entry poit
; import data in the same section
data import
librarys kernel32,user32,winmm
from kernel32,\
ExitProcess,std
from user32,\
MessageBoxA,std
from winmm,\
mciSendStringA,std
end data
start:
MessageBoxA<0,_message,_caption,MB_ICONQUESTION+MB_YESNO>
cmp eax,IDYES
jne exit
mciSendStringA<_cmd_open,0,0,0>
mciSendStringA<_cmd_eject,0,0,0>
mciSendStringA<_cmd_close,0,0,0>
exit:
ExitProcess<0>
_message db 'Do you need additional place for the beer?',0
_caption db 'Desktop configuration',0
_cmd_open db 'open cdaudio',0
_cmd_eject db 'set cdaudio door open',0
_cmd_close db 'close cdaudio',0
new calling conventions can be added,just inserting other match sections:
;------------------------------
match =c,conv
\{
make_cmac function
\}
;------------------------------
replacing =c with other identifier like =pas and providing another make_mac macro.
well what do you think?