Hi friends,

Originally, the tool was intended for Fasm, by the time, I decided to extend the features of my tool, it supports various assemblers Masm,Tasm,LzAsm,GoAsm and finally my little "scanning" tool can be used with HLA.

So what does exactly the scanner? It reads an asm source file and looks for "invoked" functions which are originally external functions and then it creates a file containing a list of external function declarations.

Let's consider this simple FASM example:
 


format PE GUI 4.0
entry start

include '%fasminc%\win32a.inc'

section '.data' data readable writeable

text db "Hi! I'm the example program!",0
caption db "Win32 Assembly",0

section '.code' code readable executable
start:
invoke MessageBox,0,text,caption,MB_OK
invoke ExitProcess,0

include 'Msgbox.imp'




scan Msgbox.asm

The resulting Msgbox.imp file:


section '.idata' import data readable writeable

library kernel32,'kernel32.dll',\
user32,'user32.dll'

import kernel32,\
ExitProcess,'ExitProcess'

import user32,\
MessageBox,'MessageBoxA'


So, what is the benefit of using this technique based on creating the list with the "just necessary" function declarations? Simply, it reduces the work of the assembler\compiler which means "reduced assembly time \ faster compilation"

To apply this technique to HLA, I created two macros, invoke for stdall API functions and cinvoke for C style functions:


#macro invoke( varying[] );

?counter := @elements( varying )-1;
#while( counter >0 )
?temp1:=varying[counter];
#if (@peekChar(temp1,'&')==true)
?temp2:=@substr(temp1,1,@length(temp1)-1);
#if (@class(@eval(temp2))==4)
pushd(ebp);
add(@eval(@offset(@eval(temp2))),(type dword [esp]));
#else
pushd(@text(varying[ counter ]));

#endif
#else
pushd(@text(varying[ counter ]));
#endif
?counter := counter - 1;
#endwhile
call(@text(varying[0]));
#endmacro;

#macro cinvoke( varying[] );

?counter := @elements( varying )-1;
#while( counter >0 )
?temp1:=varying[counter];
#if (@peekChar(temp1,'&')==true)
?temp2:=@substr(temp1,1,@length(temp1)-1);
#if (@class(@eval(temp2))==4)
pushd(ebp);
add(@eval(@offset(@eval(temp2))),(type dword [esp]));
#else
pushd(@text(varying[ counter ]));

#endif
#else
pushd(@text(varying[ counter ]));
#endif
?counter := counter - 1;
#endwhile
call(@text(varying[0]));
add(4*(@elements(varying)-1),esp);
#endmacro;


Notice that you can get the address of local symbols with the "enhanced" & operator:


var
wc: w.WNDCLASSEX;
msg: w.MSG;
hwnd: dword;
.
.
.
invoke(GetMessage,&msg,NULL, 0, 0 );
breakif( !eax );
invoke(TranslateMessage,&msg );
invoke(DispatchMessage,&msg );


A quick demonstration:


// Iczelion's tutorial #2: MessageBox

program msgBoxDemo;
#include( "w2.hhf" )
#include( "invoke.hhf" )

static

#include("Msgbox.imp")

caption:string:="Iczelion's tutorial no.2";
msg:string:="Win32/HLA Assembly is Great!";

begin msgBoxDemo;

invoke(MessageBox,
0,
msg,
caption,
w.MB_OK
);

end msgBoxDemo;




scan Msgbox.hla -h



Msgbox.imp file:


MessageBox : procedure;
external("__imp__MessageBoxA@16");


w2.hhf is a smaller version of the original windows include file w.hhf It doesn't contain any API function declaration.

You can check the attachment to see some HLA examples adapted for faster compilation.

The tool doesn't support yet nested include files, to "scan" a project composed of source files main.hla, string.hla and graphproc.hla, you create a file with the .prj extension.

Myproject.prj:


main.hla
string.hla
graphproc.hla



To run the scanner:


scan Myproject.prj -h


To get more information about the scanner:

http://board.flatassembler.net/viewtopic.php?p=3729
http://www.asmcommunity.net/board/viewtopic.php?t=13287
Posted on 2004-08-28 07:20:28 by Vortex
vortex,

This is a really useful tool. When I first tried it I thought it would be really useful for HLA and I'm grateful that you've finally added HLA support. :)But I think I would have to adjust to using invoke for api functions. :-D
Posted on 2004-08-28 09:32:23 by Odyssey
Hi Odyssey,

Yes, you are right about the adjustment problem. Theoretically, it may be possible to develop the tool to search directly the API functions, it should be an interesting programming practice to find a suitable algorithm for such a process. My modest efforts are intended to discover the powerfull macro features of HLA.
Posted on 2004-08-28 13:03:40 by Vortex
Great work. Suggestion - instead of specifying DLL names in an .ini file, you can create your own database of API functions.

You can use the command

link -DUMP -EXPORTS xxx.lib

to get a listing of the exports of a particular lib file.

Using this technique you can create a big listing of all the API functions which you can then search at run time.
Posted on 2004-12-20 05:52:28 by gfalen
Hi gfalen,

Thanks for your kind words. The first versions of my tool ( V1.0 and V2.0 ) used the database technique you mentioned but I didn't support HLA at that time. The members of the forum recommended me that it should be better to search DLLs instead of database, that's why I changed the method.

The attachment feature of the board is disabled for a while. If you would like to get the HLA example, please feel free to send me a PM with your e.mail address as the latest version of scan supports nested include files.
Posted on 2004-12-20 12:05:42 by Vortex
Hi Vortex.

This would be a cool tool to use automated from make-files and IDE's

I'm going to try it out and see how much it reduces HIDE full rebuild time (has about 17 units and processes about 20mb of source for full-rebuild).
Posted on 2004-12-20 21:06:36 by Kain
Hi Kain,

The latest version V3.33 can be obtained from Privalov's flatassembler forum. This version supports nested include files. ( except files pointed by environment variables )
Posted on 2004-12-21 11:56:24 by Vortex
Scanner V3.34 :

Now, the invoke macro is reduced to a very simple form:


#macro invoke;
#endmacro;


The use of invoke macro is easy compared to the previous version:


invoke GetModuleHandle(0);


The tool supports nested include files. To reduce the processing time of the tool,by-pass the include files which doesn't contain any API function, this is possible by typing Invoke with uppercase I :


#Include( "strings.hhf" )
#Include( "memory.hhf" )
#Include( "args.hhf" )
#Include( "conv.hhf" )


Click here to get the attachment.
Posted on 2005-01-18 14:23:48 by Vortex