FASMLIB
*******
This is the main module which has to be always included if you want to use
FASMLIB. It declares things internally used (and you should use them too when
you understand how). It also has to be included FIRST.


idata / udata
=============
- This macro is used to declare data, but have them defined at other place than
where they are declared. For example when you have code in modules:
	module1.inc
	  module1data
	  module1code
	module2.inc
	  module2data
	  module2code
	main.asm
	  include 'module1.inc'
	  include 'module2.inc'
	  maindata
	  maincode
Then compiled file has this layout:
	  module1data
	  module1code
	  module2data
	  module2code
	  maindata
	  maincode
But you usually want to have data and code in groups (data and code section).
These macros allow you to do so, by enclosing all defined data inside macro
(idata{} or udata{}) and invoking all such macros later with other special
macro (IncludeAllData). So in prevoius example you would do this:
	module1.inc
	  idata {module1data}
	  module1code
	module2.inc
	  idata {module2data}
	  module2code
	main.asm
	  include 'module1.inc'
	  include 'module2.inc'
	  idata {maindata}
	  maincode
	  IncludeAllData
and you would get:
	module1code
	module2code
	maincode
	module1data
	module2data
	maindata

- You can indent idata/udata blocks just like any macro:
	idata
	{
	  mydata1 db 3
	  mydata2 dq 1,2,3,4
	}

- There are two macros: "idata" to declare initialized data (with known initial 
value) and "udata" for uninitialized data (with unknown initial value). "idata"
works as described in example, "udata" only counts total size of data enclosed
in these blocks and reserves this amount of bytes (and declares all labels). 
So this:
	udata {mydata: times 100 db %} ;100 bytes
	udata {mystring db 'Hell o' world',0} ;14 bytes
	IncludeAllData
becomes: (something like)
	..res: rb 114
	label mydata at ..res
	label mystring byte at ..res+100
or effectively same code, but easier to understand:
	mydata: rb 100
	mystring rb 14

- Because reserving data only have effect at end of the file (at other place data
has to be contained in executable, at the end of file you only mark size of
additional data in file header), so you should always place IncludeAllData as
last data definiton in file.

- You can include initialized and uninitialized data separately, with
IncludeIData and IncludeUData macros. For clearness, definition of
IncludeAllData looks like this:
	macro IncludeAllData {
	  IncludeIData
	  IncludeUData
	}

- To use idata or udata inside macro, you must escape "{" and "}" and contents
of idata/udata just like with other macros:
	macro MyMacro
	{
	  idata \{
	    a db 'aaaaaaa',0
	  \}
	}

- Don't forget that defining with idata/udata is preprocess-time thing, so it
cannot be conditioned with (assembly time) "if" directive. This code:
	if 0 > 1
	  idata {db 0}
	end if
would define "db 0" anyway. To achieve conditioning you can place condition
inside idata/udata block:
	idata {
	  if 0 > 1
	    db 0
	  end if
	}

- idata/udata is just usual macro, so you can use all macrofeatures inside it,
but rather don't do it unless you are sure about what you are doing:
	idata {
	  local ..len ;macrofeature
	  pascal_style_string db ..len
	  db "hi, this is long string and i am lazy to count it's size",0
	  ..len = $-pascal_stryle_string-1
	}




ifndef
======
- sometimes you need to know if symbol (numeric constant/label) is alredy defined
previously in file. There is "defined" operator, but it checks in entire source:
	if ~defined a		;this contition is false
	  display 'defined'	;and this will won't be assembled
	end if
	a = 1
And construct like this cannot be used too:
	if ~defined a
	  a:
	end if
because it is logical paradox ("if a is not defined, then it is defined") and
it's behavoir cannot be defined clearly.

- That's why there is macro, which checks whether symbol is defined previously
in file:
	b:
	ifndef a ...	;true
	ifndef b ...	;false
	a:

- You can nicely use it to let caller define some value for module, like exmaple
from strlib:
	;minimum string length
	ifndef STR_MINSTRLEN		;if user didn't define STR_MINSTRLEN
	  STR_MINSTRLEN = 16		;then use default value 16
	end if
User specifies it this way:
	STR_MINSTRLEN = 16		;can be anywhere before include
	include 'fasmlib/strlib.inc'



macro libcall proc*,[args]
==========================
this macro is meant to call FASMLIB (and compatible user-defined) routines. It
is extended version of Tomasz Gryszstar's stdcall macro. It is compatible with
stdcall, but has some extended features to work nicer with FASMLIB.

First (required) argument is procedure name. Procedure must be declared with
"proc" macro (TODO). Then comes arguments. There can be no arguments too. 
Argument can be either value pushable by "push dword value" (label, number, 
numeric constant, memory-addressed dword) or one of following:

- if arg is a string, it is declared inside "idata" block using "db" directive,
  ended with 0 byte, and pointer to it is pushed. Example of what is considered
  string: "aaa", '', <"line1",10,'line2'>,<1,2>. Pushing code looks like this:
	idata {
	..address db "line1",10,'line2',0
	}
	push dword ..address

- if arg is in form "double var", "double [var]", "double ptr var" then two
  pushes are used to push the value.

- if arg is in form "addr var", then, if var isn't directly pushable (like
  "ebp+4") address is filled into register with lea and pushed.
	local LocalVariale ;label LocalVariable dword at ebp + 4
	libcall module.proc, addr LocalVariable

  In FASMLIB implementation, (unlike in many other implementations of "addr")
  register is preseved, so you can use constructs like:
	libcall module.proc, edx, addr localvariable.

- if arg is in form "<libcall ...>" then this call is done first and return 
  value in eax is pushed. This allows you nested procedure calls:
	;proc1 takes 3 arguments, proc2 takes 1 argument
	libcall proc1, 1, <libcall proc2, 2>, 3
  becomes: (not exactly, see further)
	push dword 3	;for proc1
	push dword 2	;for proc2
	call proc2
	push eax	;for proc1
	push dword 1	;for proc1
	call proc1

  Additionally, because all FASMLIB procedures return error in CF, this macro
  allows you to check all erros with one conditional jump, you can use this:
	libcall proc1, 1, <libcall proc2, 2>, 3
	jc .error	;this checks both error from proc1 and proc2
  generated code looks like this: (this is the real one :)
	push dword 3	;for proc1
	push dword 2	;for proc2
	call proc2
	jnc ..noerr
	add esp,4	;size of things on stack pushed by this macro until now
	stc		;ADD changed it
	jmp ..end
	..noerr:
	push eax	;for proc1
	push dword 1	;for proc1
	call proc1
	..end:

  TODO? i think pushf sometimes takes too long when virtualized, we could
  create new stack frame for each nested call to restore ESP?

