
 ----------------------------------------------------------------------------

         The XAssembler Compiler v3.12 (16-bit DOS) - User's Manual

 ----------------------------------------------------------------------------


                Keep in mind that english is not my every-day
                  language ... and don't laugh too much ;-)



 Table of Contents
 -----------------

 1. Introduction
 2. What's new since version 2.3?
 3. XAssembler syntax
  3.1. Instructions and registers
  3.2. Version 2.3 compatibility
 4. Program structure
  4.1. Compilation modes
  4.2. Output file format
  4.3. Stack and heap
  4.4. Block allocation
  4.5. Setting base address
  4.6. Data and code alingment
  4.7. Limiting instruction set
  4.8. Symbols
  4.9. Comments
 5. Data
  5.1. Types
  5.2. Constants
  5.3. Variables
  5.4. Auto-filling
  5.5. Local data *
  5.6. Creating data files
  5.7. Structures *
  5.8. Floating-point numbers
 6. Procedures
  6.1. Procedure types
  6.2. Interrupts
  6.3. Parameters *
  6.4. Safe exit from procedure
 7. Main unit
 8. Labels
 9. Functions
  9.1. Ofs function
  9.2. TypeOf function
  9.3. SizeOf function
  9.4. High function *
  9.5. Low function *
  9.6. Argument type for High and Low functions *
  9.7. Functions overlapping *
 10. Numeric expressions *
 11. Temporary functions *
 12. Macros *
 14. Conditional compilation *
  14.1. IF/ELSE/ELSEIF/ENDIF construction *
  14.2. Conditional expressions *
  14.3. IFDEF and IFNDEF conditional directives *
 14. Loops *
  14.1. REPEAT/UNTIL loop *
  14.2. FOR/ENDFOR loop *
  14.3. WHILE/ENDWHILE loop *
  14.4. Temporary variables *
 15. Symbol references
  15.1. Constants
  15.2. Variables
  15.3. Procedures and labels
  15.4. Macros *
  15.5. Tepmorary functions *
  15.6. "Dot" references *
  15.7. Direct addressing and type casting
  15.8. Default segment change
  15.9. CALL, JMP i Jcc jumps addressing
  15.10. Local variable and parameter references *
  15.11. Forward references *
  15.12. Data/code modification *
 16. Local directives (switches)
 17. Including files
 18. Inserting code
  18.1. Segment incompatibility error
 19. 32-bit applications
  19.1. Code images
  19.2. DPMI (DOS Protected Mode Interface)
  19.3. Windows *
  19.4. Linux *
  19.5. COFF, MSCOFF and ELF object files *
 20. Passing messages in program source
 21. Forced compilation abort
 22. Aliases *
 23. Libraries and object files *
 24. Program compilation
  24.1. Starting the compiler
  24.2. Options
  24.3. Reported errors and warnings
 25. Program optimization
 26. Predefined constants
 27. Examples
 28. Final word

 Add-ons

 29. List of compiler options
 30. List of compiler directives
 31. Error codes
 32. XAssembler in net

 * - Not implemented in this version :(



 ----------------------------------------------------------------------------
 1. Introduction
 ----------------------------------------------------------------------------

 Welcome all :-) This document explains the rules of  making  programs  using
 XAssembler compiler.  The internal workings of a PC-type  computer  are  not
 discussed here however having basic knowledge in  this  matter  is  at least
 recommended.

 What is XAssembler?

 It is a compiler of assembly language for x86  family  processors,  equipped
 with its own (a bit different) syntax, capable of producing both 16-bit  and
 32-bit applications.

 This document assumes, that reader posses  at least  basic  knowledge  about
 x86 processors, instructions, addressing modes  etc.  If  not,  I  recommend 
 reading a good book or documentation from one of chip  manufacturers,  which
 can be found easily on internet :)



 ----------------------------------------------------------------------------
 2. What's new since version 2.3?
 ----------------------------------------------------------------------------

 Many things. First of all one executable instead of two. Of course this made
 me to write entirely new code. New compiler is  faster,  more  flexible  and
 safe in handling  unpredicted  situations - thanks  to  compiler's  internal
 control mechanism. Error reporting system has been  improoved,  no  need  to
 think what printed out message means.  Added long file name  support  allows
 comfortable work in OSes that  support  LFN's.  No  more  source  file  size
 restriction. Also the file read subroutine works better.
 
 The compiler is many times faster than its predecessors. Optimized for speed
 lexical analysis module is able to  process  up  to  3 MB  source  code  per
 second !!! Symbolic scanner uses check sums for symbol  lookup. Additionally
 a symbol caching mechanism is implemented  to  improove  symbol  processing.
 Because of this its performance is much higher than  in  previous  versions.
 The result of implementing these features is nominal processing speed around
 75000 lines per second for typical source code.

 As for syntax, few directives has been  added  allowing  more  control  over
 compilation process and generated code. Data  definitions  capabilities  are
 highly improoved.

 The Compiler have built in processing module, allowing usage of  compilcated
 numeric expressions directly in program code. The module works transparently
 on every level - it matches up  automaticly  to  used  data  type,  allowing
 calculations on values extending the range of given type.

 Xassembler uses its own library file  format.  It  can  be  used  to  create
 procedure/data libraries for later easy usage in programs.



 ----------------------------------------------------------------------------
 3. XAssembler syntax
 ----------------------------------------------------------------------------

 The compiler accepts plain text source files  (with standard or reversed EOL
 marker), any size.

 Recognized numeric systems  are :  decimal  (integer and real),  binary  and
 hexadecimal.

 The compiler recognizes real numbers by dot, written in  both  standard  and
 scientific notation.


 Exapmles :

   10       integer
   10.0     real
   1.0e1    real (scientific notation)

   1010b    binary ("b" after)

   $A       hexadecimal ("$" before)
   0Ah      hexadecimal ("h" after) *

 * - When using "h" method for hexadecimals the number must start
     with a digit  (letters "A".."F" must be preceeded with 0).


 Symbol names can contain letters, digits and characters  "_",  "@"  and  "?"
 ("@" and "?" can not be first characters of the name).  Additionaly,   names
 can't start with digit otherwise they'll  be  treated  as  numbers.  Maximum
 symbol name length is 90 characters.

 Names and form of machine code instructions follows Intel standard. The only
 differences can be found when using compiler functions or memory references.
 This subject is discussed later.



 3.1. Instructions and registers
 -------------------------------

 Instructions recognized by compiler (in order 386, FPU, 486, Pentium) :

  AAA, AAD, AAM, AAS, ADC, ADD, AND, ARPL, BOUND, BSF, BSR, BT, BTC, BTR,
  BTS, CALL, CBW, CDQ, CLC, CLD, CLI, CLTS, CMC, CMP, CMPS, CMPSB, CMPSW,
  CMPSD, CWD, CWDE, DAA, DAS, DEC, DIV, ENTER, ESC, HLT, IDIV, IMUL, IN,
  INC, INS, INSB, INSW, INSD, INT, INTO, IRET, IRETD, JMP, JCXZ, JECXZ,
  JA, JB, JC, JE, JG, JL, JO, JP, JS, JZ, JNA, JNB, JNC, JNE, JNG, JNL,
  JNO, JNP, JNS, JNZ, JAE, JBE, JGE, JLE, JPE, JPO, JNAE, JNBE, JNGE, JNLE,
  LAHF, LAR, LDS, LEA, LEAVE, LES, LFS, LGDT, LGS, LIDT, LLDT, LMSW, LOCK,
  LODS, LODSB, LODSW, LODSD, LOOP, LOOPE, LOOPZ, LOOPNE, LOOPNZ, LSL, LSS,
  LTR, MOV, MOVS, MOVSB, MOVSW, MOVSD, MOVSX, MOVZX, MUL, NEG, NOP, NOT,
  OR, OUT, OUTS, OUTSB, OUTSW, OUTSD, POP, POPA, POPAD, POPF, POPFD, PUSH,
  PUSHA, PUSHAD, PUSHF, PUSHFD, RCL, RCR, REP, REPE, REPZ, REPNE, REPNZ,
  RET, RETN, RETF, ROL, ROR, SAHF, SAL, SAR, SBB, SCAS, SCASB, SCASW,
  SCASD, SETC, SETNC, SETO, SETNO, SETS, SETNS, SETP, SETPE, SETNP, SETPO,
  SETZ, SETNZ, SETE, SETNE, SETG, SETNG, SETGE, SETNGE, SETL, SETNL, SETLE,
  SETNLE, SETA, SETNA, SETAE, SETNAE, SETB, SETNB, SETBE, SETNBE, SGDT,
  SHL, SHLD, SHR, SHRD, SIDT, SLDT, SMSW, STC, STD, STI, STOS, STOSB,
  STOSW, STOSD, STR, SUB, TEST, VERR, VERW, WAIT, XCHG, XLAT, XLATB, XOR


  F2XM1, FABS, FADD, FADDP, FBLD, FBSTP, FCHS, FCLEX, FNCLEX, FCOM, FCOMP,
  FCOMPP, FCOS, FDECSTP, FDIV, FDIVP, FDIVR, FDIVRP, FFREE, FIADD, FICOM,
  FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FINCSTP, FINIT, FNINIT, FIST, FISTP,
  FISUB, FISUBR, FLD, FLDZ, FLD1, FLD2E, FLD2T, FLDG2, FLDN2, FLDPI, FLDCW,
  FLDENV, FMUL, FMULP, FNOP, FPATAN, FPREM, FPREM1, FPTAN, FRNDINT, FRSTOR,
  FSAVE, FNSAVE, FSCALE, FSIN, FSINCOS, FSQRT, FST, FSTP, FSTCW, FNSTCW,
  FSTENV, FNSTENV, FSTSW, FNSTSW, FSUB, FSUBP, FSUBR, FSUBRP, FTST, FUCOM,
  FUCOMP, FUCOMPP, FWAIT, FXAM, FXCH, FXTRACT, FYL2X, FYL2X1P

  FDISI, FNDISI, FENI, FNENI, FSETPM (added for compatibility)


  BSWAP, INVD, INVLPG, WBINVD


  CMPXCHG, CMPXCHG8B, CPUID, RDMSR, RDTSC, RSM, WRMSR


 General purpose registers :
  - AL,AH,AX,EAX,
  - BL,BH,BX,EBX,
  - CL,CH,CX,ECX,
  - DL,DH,DX,EDX,
  - SI,ESI,
  - DI,EDI,
  - SP,ESP,
  - BP,EBP.

 Coprocessor registers :
  - ST,ST0,ST1,ST2,ST3,ST4,ST5,ST6,ST7.

 Segment registers :
  - CS,DS,ES,SS,FS,GS.

 Control registers :
  - CR0,CR2,CR3,CR4.

 Debug registers :
  - DR0,DR1,DR2,DR3,DR4,DR5,DR6,DR7.



 3.2. Version 2.3 compatibility
 ------------------------------

 Read this only if you've been using old version :)

 Because of important changes in basic  rules  of  program  structure  it  is
 necessary to modify old sources so they could be compiled with  new  version
 of the compiler.

 For this purpose the following must be done :
  - use Small or Near compilation mode (see p. 4.1), *
  - modify MEMORY directive (see p. 4.3),
  - remove VAR and CONST directives,
  - put file names in ".." when using INCLUDE directive,
  - remove INTERRUPT directives (see p. 6.2 - how to write interrupts),
  - use INLINE directive instead of CODE (just different name),
  - use BEGIN directive instead of PROGRAM (as above).

 * - Near mode is the only compilation mode fully compatible with old version
     of the compiler although it doesn't have  to  be  used  if  the  program
     itself don't require exact parameters.

 Version 2.3 allowed multiple symbols with the same name  while  new  version
 does not allow such definitions. The solution to this problem is  to  change
 all duplicated names to unique ones.

 Besides above elements the compiler is fully compatible with old version; no
 need to modify separate instructions or overall program structure.



 ----------------------------------------------------------------------------
 4. Program structure
 ----------------------------------------------------------------------------

 Typical xassembler program is divided into three functional blocks : initial
 block, data block, code block.

 Initial block contains informations about :
  - compilation mode (MODE directive),
  - stack and heap size (MEMORY directive),
  - code origin (ORG directive),
  - alingment (ALIGN directive),
  - used libraries/objects (USE directive)
  - start jump ({j-}) or DS/ES segment initialization ({s-}).

 Data block contains :
  - constants (SET directive),
  - global variables (DEF directive and its co-directives),
  - aliases (ALIAS directive).

 Code block contains :
  - procedures (PROC/END directive),
  - main unit (BEGIN/END directive),
  - local labels,
  - global labels (LABEL directive),
  - constants (SET directive),
  - local varaibles (directives DEF and LOCAL).

 Additionally, in data and code blocks, following  directives  are  allowed :
 INLCUDE, MSG and STOP. Other directives are used in special cases, they  are
 described in next chapters.

 Blocks in source code always follow the same  order;  using  directive  that
 does not belong to given block indicates the beginning of  next  block,  for
 example LABEL indicates the beginning of code block.

 Of course such description doesn't  explain  everything  so  it's  time  for
 example program.


   ; --- initial block
   MODE com


   ; --- data block
   DEF text = 'XASM rulez :D',13,10,36


   ; --- code block ---
   PROC print

     mov  ah, 9
     int  21h

   END

   ; --- main unit (belongs to code block) ---
   BEGIN

     mov  dx, ofs tekst
     call print

     ret

   END


 The source can be treated differently by the compiler; because of that  none
 of the mentioned blocks is required to be present (however in most cases the
 program should contain at least code block).



 4.1. Compilation modes
 ----------------------

 XAssembler offers five compilation modes. 

 Bin - the simplest mode.  Allows to create single-segment (data and code are
   located in one segment) images of 16-bit code.  Ideal for boot-sectors and
   ready to use fragments of code.
   Max file size : 64k.

 Com - same as Bin, but with ORG set permanently to 100h. This mode should be
   used to create 16-bit COM programs only.
   Max file size : 64k - 256 (PSP) - 2 (word on stack) = 65278 bytes.

 Small - similar to previous modes. Generates 16-bit EXE programs.
   Max file size : 64k.

 Near - data and code are placed in different segments. This is the only mode
   fully compatible with version 2.3. Generates 16-bit EXE programs.
   Max file size : 64k (code) + 64k (data) = 128k (131072 bytes).

 Flat - 32-bit version of Bin mode. Generates 32-bit code images.  Allows  to
   create DPMI programs and applications for popular 32-bit OS-es.  Max  file
   size depends on chosen output file format (see p. 4.2).

 Selected mode is set with MODE directive.

   MODE mode_name

 Mode names are :  Bin, Com, Small, Near and Flat.  MODE  directive  must  be
 placed as first in source code. If no MODE directive is present the compiler
 uses default Com mode.


 Modes that create 16-bit EXE programs put additional limitation  on  maximum
 program size (code + data + stack + heap). It must not exceed 600  kilobytes
 (600k = 614400 bytes = 38400 paragraphs). Larger applications  will  not  be
 loaded by DOS due to memory size limit in real mode.



 4.2. Output file format
 ----------------------------

 Flat mode offers various formats of output file. The following  formats  are
 available :

   dpmi   - executable file (DOS, 32-bit)
   pe     - executable file (Windows)
   coff   - COFF object file (Common Object File Format)
   mscoff - Microsoft's version of COFF object file
   elf    - ELF object file (Executable and Linkable Format)
   elfexe - executable file (Linux)

 Selected format is described by additional parameter of MODE directive.

   MODE flat, format

 Of course, if no format is specified the compiler gerenates code image. More
 on file formats in chapter 19.



 4.3. Stack and heap
 -------------------

 16-bit EXE programs require to specify stack and heap sizes which'll be used
 at run time. XAssembler sets default stack size to 1024 bytes and heap to 0.
 Of course these values can be changed by using MEMORY directive.

   MEMORY stack_size, heap_size

 Both sizes are given in bytes. It is required that total size of data, code,
 stack and heap must fit  into  conventional  memory - about 600k - otherwise
 operating system will not start the program. Thus maximum size for  heap  is
 600000 bytes. Minimal stack size is 16 bytes.
 
 XAssembler offers  simple  mechanism  of  accessing  declared  heap  through
 predefined constant _hseg. The size of the heap is available through  _hsize
 constant.



 4.4. Block allocation
 ---------------------

 Block placing in source code always correspond to their location  after  the
 program is loaded into memory with the exception of Near mode (where code is
 located before data) and Flat mode (some output file formats allow blocks to
 be allocated in different order). Stack location, though it is not  actually
 declared in program, is set by the compiler.

  --------------------------------------------------
   Mode                  | Block order in memory
  --------------------------------------------------
   Bin, Com, Small, Flat | data -> code -> stack *
   Near                  | code -> data -> stack
  --------------------------------------------------

  * - Size and location of the stack is unknown at compilation  time,  except
      for Small mode.



 4.5. Setting base address
 -------------------------

 Modes that create code images (Bin and Flat) allow to set base  address  for
 image - an address at which it will be loaded. ORG directive does that.

   ORG base_address

 The chosen value can not be greater than max file size for used  mode,  also
 it must allow the image to fit into segment.

 Mode Com, which also genereates code images, have base  address  permanently
 set to 100h.



 4.6. Data and code alignment
 ----------------------------

 The main purpose of aligning is to speed up the program. In some cases it is
 required (by used instructions for example). Aligning causes such allocation
 of program elements that their addresses can be divided by  specified  value
 without remainder.

 The aligning operation is done by using ALIGN directive. It allows to define
 alignment factor for entire program - global aligning.  Proper values are 2,
 4, 8 and 16. In practice using values 8 and 16 should  be  used  only  where
 they're required because they make final program size much bigger.

   ALIGN 2

 By default aligned are global data only. Procedures,  global  labels,  local
 data and labels can be also aligned if {g+} or {l+}  switch  was  used  (see
 chapter 16). Again, this causes code size to grow.

 For basic type variables XAssembler uses adaptive aligning. This means, that
 those variables which are smaller than align factor and  don't  cross  align
 boundary aren't aligned. Of course this can be disabled by {t-} switch, then
 every variable will be aligned.

 The compiler allows to align only specified part of program. More on this in
 chapter 15.



 4.7. Instruction set limiting
 -----------------------------

 XAssembler allows full control of availability of  implemented  instructions
 on the basis of processor class on which those instructions were introduced.
 Minimal supported instruction set is 386. Newer instructions can be added or
 removed freely regardles of processor class they belong to.  For details see
 chapter 16.



 4.8. Symbols
 ------------

 For XAssembler "symbol" means a string of characters linked  with  specified
 program element, which can be referenced. These references can  be  of  many
 different types independent on referenced element, thus in  compiler -> user
 communication only that name is used. It is important to realize that symbol
 can be a constant, variable, procedure or label.



 4.9. Comments
 -------------

 The ability to put commentary into source code is very important because  it
 makes it easier to understand the code later. Comments also allow to exclude
 selected part of code. XAssembler recognizes the semicolon character as  the
 beginning of the comment. Everything after it is ignored till the end of the
 line.
 
   mov ax, 1    ; commentary to the end of line


 The compiler allows to select big parts of  source  code  as  commentary  by
 using COMMENT/ENDC directive.

   mov ax, 1

   COMMENT

     any content ignored by compiler

   ENDC

   mov dx, 1


 Comments with semicolon are processed at source code reading level, they can
 be used anywhere in program.



 ----------------------------------------------------------------------------
 5. Data
 ----------------------------------------------------------------------------

 XAssembler allows definitions of data of practically  any  kind.  Unlike  in
 version 2.x the definitions themselves are much simpler and easier to use.



 5.1. Basic types
 ----------------

 XAssembler offers 7 basic types. The table below describes those  types  and
 their features.

  ----------------------------------------------------------------------
   type   | bytes | value range (signed)          | notes
  ----------------------------------------------------------------------
   BYTE   |   1   | 0..255     (-128..+127)       |
   WORD   |   2   | 0..65535   (-32768..+32767)   |
   DWORD  |   4   | 0..2^32-1  (-2^31..+2^31-1)   | single *
   FWORD  |   6   | 0..2^48-1  (-2^47..+2^47-1)   |
   QWORD  |   8   | 0..2^64-1  (-2^63..+2^63-1)   | double *
   TBYTE  |   10  | 0..2^80-1  (-2^79..+2^79-1)   | extended *
   OWORD  |   16  | 0..2^128-1 (-2^127..+2^127-1) |
   DQWORD |   16  | as above                      | alternative name
  ----------------------------------------------------------------------

  * - These correspond to real types used in high-level languages.



 5.2. Constants
 --------------

 Constants in XAssembler represent specified numeric value and  as  such  are
 not included into output file. For constant definitions SET  directive  must
 be used.

   SET const_name = const_value

 Value of the constant can be a number or numeric expression - the expression
 can not contain forward references.

 By obvious differences there are two types of constants : integer and real.

   SET a = 10     ; integer constant
   SET b = 10.0   ; real constant *

   * - see p. 5.8

 Independent on constant type it represent some  value,  which  can  be  used
 later in any place in program.

 Constant definitions can be located in any block of the program,  however it
 is important to remember that despite  their 'globality' every  constant  is
 visible only after its definition.



 5.3. Variables
 --------------

 Variables in XAssembler are data that can  be  modified  by  the  program in
 any moment of execution. Variables are difined with DEF directive. There are
 two types of variables : non-type variables and basic-type variables.

 Non-type variables allow to define any strings of characters or numbers with
 no specified type (by default all elements of such string are bytes).

   DEF txt = "The XAssembler Compiler",13,10,36

 Additionally, the compiler allows setting different type to each element and
 by that creating mixed variables.

   DEF txt2 = "The XAssembler Compiler", word 0A0Dh, 36

 Another feature of non-type variables is the possibility of  using  external
 files as data source. It can be done with FILE directive.

   DEF font = FILE "myfont.dat"


 Basic-type variables always have specified type. They are usable in creating
 single variables or any-size arrays.

   DEF data : BYTE
   DEF tab  : [10]           ; 10 bytes array
   DEF tab2 : DWORD [4]      ; 4 double word array

 Such variables can be uninitialized  (as in example above)  or  initialized.
 Setting initial value is done in the same way as with non-type variables.

   DEF data  : BYTE = 1
   DEF data2 : BYTE = 1,2,3
   DEF tab   : [10] = 1,2,3,4,5,6,7,8,9,0
   DEF tab2  : DWORD [4] = 0,2AF000C0h,8192,0Fh

 Single variables can be extended to arrays of any length without  specifying
 the size in brackets (see 2nd line in example above).

 The compiler guarantees value 0 for uninitialized  variables.  There are two
 excpetions from that rule :
  - using "-x" option in mode Near (see chapter 23),
  - using Flat mode features - additional output file formats allow to define
    uninitialized data in .bss section, which  content  at  compile  time  is
    unknown.


 Both non-type and basic-type variables allow  so  called  multi-definitions.
 This way more than one variable can be created with single definition.

   DEF a,b,c : WORD



 5.4. Auto-filling
 -----------------

 The auto-filling feature allows fast definitions of repeated  data  strings.
 REPEAT and TIMES (basic type variables and mixed variables) or DUP directive
 (arrays only) are used to do that.  When using definitions with auto-filling
 forward references are not available. Also the original definition type must
 remain unchanged.  Additionally the _dtp constant  (see chapter 26)  is  not
 updated after each repetition.

 Auto-filling in definitions of non-array variables can be done in  two  ways
 by using TIMES directive only or two paired  directives  REPEAT/TIMES.  This
 allows to repeat any part of definitions. The basic form of such  definition
 looks follows this scheme :

   DEF name = repeated_element TIMES repeat_counter
   DEF name = REPEAT el1,el2,...,elN TIMES repeat_counter

 As presented the repeated element(s) is placed  before  and  repeat  counter
 after TIMES directive. The counter value can be a  numeric  expression.  The
 example below shows definitions with REPEAT and TIMES directives  and  their
 simple (unrolled) counterparts.

   DEF a = 1,2 TIMES 5          ->   def a = 1,2,2,2,2,2
   DEF b = REPEAT 1,2 TIMES 5   ->   def b = 1,2,1,2,1,2,1,2,1,2

 The TIMES directive and REPEAT/TIMES pair can be used many times in the same
 definition. 


 Auto-filling in initialized arrays is done with DUP directive and its  quite
 different from the case described above. There's no repeat  counter  because
 it isn't needed (the compiler fills the array to its size given  earlier  in
 definition) and the repeated elements are placed after  directive.  This  is
 how the basic form of such definition look like :

   DEF name : type [size] = DUP repeated_element
   DEF name : type [size] = DUP el1,el2,...,elN

 A single element or any number of elements can be repeated - the limit begin
 the array size. XAssembler allows to define a part  of  table  using  normal
 method and later fill it up using DUP directive.

   DEF name : type [size] = el1,el2, DUP repeated_element
   DEF name : type [size] = el1,el2, DUP el3,el4,...,el5

 The examples below demonstrate definitions  with  DUP  directive  and  their
 simple (unrolled) counterparts.

   DEF a : [5] = DUP 0          ->   def a : [5] = 0,0,0,0,0
   DEF b : [5] = DUP 1,2        ->   def b : [5] = 1,2,1,2,1
   DEF c : [5] = 1,2, DUP 0     ->   def c : [5] = 1,2,0,0,0
   DEF d : [5] = 1,2, DUP 3,4   ->   def d : [5] = 1,2,3,4,3



 5.6. Creating data files
 ------------------------

 One of additional XAssembler features, pretty far from  programming, is  the
 ability to create any data files. It is possible because of specifics of Bin
 and Flat modes, which allow total non-presence of code in program. Below is
 the simple template of such "program".

   MODE bin    ; or flat
   {j-}        ; disable start jump

   ; data definitions which will made the file

   END

 Starting the compiler with the file name as the only parameter will generate
 binary file with proper content. Selecting appropiate mode  should  not be a
 problem. For files smaller than 64k mode Bin is good, for larger it's  Flat.
 Both modes differ when it comes to  characteristics  of  certain  functions,
 which fact should also be considered.



 5.8. Floating-point numbers
 ---------------------------

 XAssembler recognizes two kinds of floating-point numbers:
  - single (32 bits, DWORD type, up to 8 significant digits),
  - double (64 bits, QWORD type, up to 15 significant digits).

 In source files allowed lengths are : integer  part  up  to  15  digits  and
 fraction part up to 20 digits. Exceeding these lengths will cause  an  error
 (in case of integer part) or that rest of digits will be igonred (in case of
 fraction). Total length of the  string  representing  floating-point  number
 cannot exceed 90 characters.

 XAssembler allows floating-point usage in constant and variable  definitions
 and also as instruction arguments. Due to spefific features of these numbers
 DWORD or QWORD type is required in such expressions (the latter  is  allowed
 only in data definitions).

 As for constants it is important to remember that  they  do  not  poses  any
 specific type, and the compiler adjusts their value to type used in constant
 reference. Thus the limitation of using only floating-point values of  DWORD
 type in constant definitions. Additional problem shows up when a  value  0.0
 is defined as constant. In such case a warning is displayed because later at
 compilation time it is not possible to determine wheter  the  constant  is a
 floating-point 0.0 or integer 0, which may cause unexpected  logical  errors
 like assigning value 0.0 to BYTE type variable.


 Examples of using floating-point numbers.

   SET pi = 3.1415            ; constant (automaticly DWORD type)

   DEF alfa : dword = 0.01    ; DWORD type variable
   DEF beta = qword -1.27     ; variable with forced QWORD type

   push dword 1.5             ; using f-p number directly as instruction
                              ; argument (DWORD type only)


 Encoding of floating-point numbers is done according to IEEE-754 standard
 which is used in x87 family cooprocessors.



 ----------------------------------------------------------------------------
 6. Procedures
 ----------------------------------------------------------------------------

 Procedure is an closed fragment of code, which can be  called  and  executed
 multiple times. The content of the procedure is located between PROC and END
 directives.

   PROC procedure_name

   ; procedure content ...

   END

 In the place of END directive the compiler automaticly  puts RET instruction
 unless ENDR direcrive or {r-} switch was used (see chapter 15).



 6.1. Procedure types
 --------------------

 XAssembler uses only one type of procedures, NEAR. It's a direct  result  of
 single-segment program construction, where acces to every procedure is  made
 through such calls.

 Of course it is possible to create FAR procedure. To do that simply  replace
 END directive with ENDR and insert RETF instruction.



 6.2. Interrupts
 ---------------

 Creating interrupt service procedures is easy. XAssembler offers two ways to
 do that.


 First is to use ENDI directive instead of  END  (the  compiler  will  insert
 IRET/IRETD instruction depending on current code type).

   PROC interrupt_1

   ENDI  ; <- IRET (Bin, Com, Small and Near) or IRETD (Flat)


 The second is to use ENDR directive  (or {r-} switch)  and  manually  insert
 IRET/IRETD instruction.

   PROC interrupt_2

   iret    ; or IRETD

   ENDR    ; ENDR directive doesn't insert RET instruction

 

 6.4. Safe exit from procedure
 -----------------------------

 XAssembler offers EXIT directive that allow to safely  leave  the  procedure
 regardles of its type, parameters or local variables. The reason for that is
 to make coding procedures easier.

   PROC my_proc

     cmp eax, 1
     je  set_flag
     mov [ebx], 0

     EXIT             ; <- RET instruction

   set_flag:
     mov [ebx], 1

   END                ; <- RET instruction

 Using this method is not required by any means but it makes the source  code
 more clear. Of course the EXIT directive cannot be  used  inside  procedures
 called as FAR for obvious reasons (the RET instruction will take  only  half
 of the address from stack).



 ----------------------------------------------------------------------------
 7. Main unit
 ----------------------------------------------------------------------------

 The main unit contains the code, which will be executed directly  after  the
 program is started. It starts with BEGIN and ends  with  an  END  directive.
 Depending on used compilation mode, the BEGIN directive may cover additional
 instructions.


 In modes that generate images (Bin, Com and Flat) the  compiler  automaticly
 puts at the beginning of the code additional  jump  instruction  to  address
 specified by BEGIN directive.

   jmp begin_directive   --
                           |
                           |
     ; data definitions    |
                           |
     ; procedures          |
                           |
                           |
   BEGIN                 <-

   END

 If there's no data or procedures before main unit  then {j-} switch  can  be
 used to skip that additional JMP instruction (see chapter 15).


 In modes Small and Near (16-bit EXE programs) the  entry  point  address  is
 specified in the executable file header. However, the  program  itself  must
 set the value of DS register to gain access to its data.  To  fullfill  this
 requirement  XAssembler  automaticly  puts  proper  instructions  that  will
 initialize DS and ES segments in the place of BEGIN directive. Depending  on
 used compilation mode different combinations of instructions are inserted.

 Small mode (4 additional bytes) :

   BEGIN  <----- push cs
            |    push cs
            |    pop  ds
             --- pop  es
   END

 Near mode (6 additional bytes) :

   BEGIN  <----- push _dseg
            |    pop  ds
            |    push ds
             --- pop  es
   END

 Similar to previous case the compiler offers {s-} switch, which will disable
 the insertion of additional instructions. However, it is  important  not  to
 forget to initialize DS manually to point to program data, after this switch
 is used.


 XAssembler doesn't put any instructions that will exit the program. If there
 are no such instructions the processor will  continue  to  execute  whatever
 bytes are there after the program's code. The programmer must take  care  of
 terminating the application in a proper way.



 ----------------------------------------------------------------------------
 8. Labels
 ----------------------------------------------------------------------------

 Labels directly specify an address in program code  segment,  which  can  be
 referenced through them. XAssembler uses two types of labels.

 Global labels, defined with LABEL directive. They  can  be  located  at  any
 address in the  code  (inside and ouside procedures/main unit)  and  can  be
 referenced from any place.

   LABEL label_name

   BEGIN

     LABEL lable_name

   END


 Local labels are placed only inside procedures/main unit.Their accessibility
 is limited only to the block of code in which they were defined.  Definition
 of local label doesn't require using any directive only the ":" suffix after
 the name.

   BEGIN

     label_name:

   END



 ----------------------------------------------------------------------------
 9. Functions
 ----------------------------------------------------------------------------

 XAssembler offers variety of functions, which accept symbols  as  arguments,
 that allow to easier creation of  the  program.  The  important  feature  of
 functions is that the returned values  can  be  treated  as  constants - the
 type-match rules do not apply to them. The exceptions are funtions  Low  and
 High, being strictly dependable on target value type.



 9.1. Ofs function
 -----------------

 Function returns symbol address inside the corresponding segment - so called
 offset. Mostly used in data references via square brackets "[..]" or passing
 parameters to system functions.

   DEF txt = 'hey!$'

   mov  ah, 9
   mov  dx, ofs txt                ; address of text to print
   int  21h


   DEF data : WORD [100]

   mov  byte [ofs data], 0         ; 1st word low byte = 0
   mov  byte [ofs data + 100], 2   ; 50th word low byte = 2


   PROC my_proc
     add al, bl                    ; instruction takes 2 bytes
     add al, cl
   END

   call ofs my_proc + 2            ; call the procedure while
                                   ; skipping the first instruction

 Of course the real usage of this function is much wider - it is shown in the
 last example above.



 9.2. TypeOf function
 --------------------

 Function returns argument type.  The  arguments  can  be  global  variables,
 local variables and procedure parameters.

 -------------------------------------------
  Symbol             | Type         | Value
 -------------------------------------------
  Variable/Parameter | BYTE         |  201
                     | WORD         |  202
                     | DWORD        |  204
                     | FWORD        |  206
                     | QWORD        |  208
                     | TBYTE        |  210
                     | OWORD/DQWORD |  216
 -------------------------------------------

 Values returned by TypeOf function correspond to the values used  internally
 by compiler.



 9.3. SizeOf function
 --------------------

 Function retunrs size of symbol in bytes. Arguments can be global and local
 variables and procedure parameters.

   DEF txt = "The XAssembler Compiler",0

   mov eax, SizeOf txt   ; eax = 24



 ----------------------------------------------------------------------------
 15. Symbol references
 ----------------------------------------------------------------------------

 XAssembler offers two basiv methods of referencing symbols, each one of them
 having specific features.

 First method is referencing by name. As implied, only symbol name is used in
 such references. These references are simplest, however  they  require  full
 type compatibility in instruction arguments.

 Second method is referencing through function where,  besides  symbol  name,
 one of the functions is present (see chapter 9). In such references the type
 is not checked but the returned value must be in required range.



 15.1. Constants
 ---------------

 XAssembler allows constant references only by name. This applys to constants
 defined with SET directive and directly used numeric values.

   SET count = 100

   mov  al, count
   mov  al, 100

 There is also available a third form of constants. Those are text constants,
 used directly in instruction arguments. Such constants  are  simply  strings
 from 1 to 4 characters in length. The compiler  converts  them  directly  to
 corresponding values. The instructions below simply do the same thing.

   mov  al, 'A'
   mov  al, 65

 The value of constant is automaticly matched to used  data  type.  Undefined
 bytes are always zeroed. The order of characters in  string  corresponds  to
 real location of bytes in memory at program execution time.

   mov dword [0], 'XASM'  ; string 'XASM' will be put into memory



 15.2. Variables
 ---------------

 When referencing by name the type of argument(s) must be the same  otherwise
 the compiler will display "type mismatch" error  message.  Because  of  that
 non-type varaibles are not available in such references.

   DEF a : BYTE
   DEF b : WORD

   mov  al, a         ; value of a will be loaded to al
   mov  dx, b         ; value of b will be loaded to dx


 In references by function only value range is checked,  so  in  the  example
 below if Ofs txt < 256 then last line will  be  compiled  properly  (because
 al=0..255).

   DEF txt = 'XASM rulez!',0

   mov eax, ofs txt   ; address of txt will be loaded to eax
   mov ax,  ofs txt   ; ... ax
   mov al,  ofs txt   ; ... al



 15.3. Procedures and labels
 ---------------------------

 In practice calling procedures and labels is no different  from  referencing
 data, only used segment changes. Basic rules are the same. Of course in such
 references only jump instructions can be used.

   PROC my_proc
   END

   BEGIN

   my_label:

     call my_proc
     call ofs my_proc

     jmp  my_label

   END



 15.7. Direct addressing and type casting
 ----------------------------------------

 In references described above there was always symbol name used and  address
 calculation was done  by  the  compiler.  The  opposite  happens  in  direct
 addressing, where  the  programmist  specifies  the  address  inside  square
 brackets. This allows to use any available address combination  provided  by
 processor. XAssembler also allows using references by  function  in  address
 specification.  Additionally, using only symbol name equals to Ofs function.
 This mean that "[data]" is equal to "[ofs data]".

 The address form depends on type of generated code : [BASE + INDEX + OFFSET]
 for 16-bit code or [BASE + INDEX*SCALE + OFFSET] for 32-bit code.  The exact
 description can be found in x86 chip documentation.

   mov  al,  [1234h]
   mov  ax,  [bx]
   mov  dl,  [bx + si - 2]
   mov  eax, [edi + ebx*2 + ofs data + 7h]

 The term "direct addressing" does not have anyuthing in common with the term
 used in x86 documentation. It only points a method of specifying the address
 in source code.

 Addtional feature of direct addressing is the possiblility of  choosing  the
 type of offset used in address, which provides more control  over  generated
 code.

   mov al, [bx - byte 2]
   mov dx, [word 1234h]
   mov eax, [dword - 2]

 Allowed types are BYTE, WORD and DWORD. Type  specification  can  be  placed
 anywhere inside the brackets, however is should be located  directly  before
 the offset value to make the source code more readable.


 Data type casting is used in instructions where memory is used as argument.
 If type is not specified the compiler uses default type (if possible).

   mov [bx], 1         ; default BYTE type is used
   mov word [bx], 1    ; casting WORD type

 It is important to remember that the default type may change  for  different
 instructions, for example in PUSH/POP it is WORD or DWORD depending on  code
 type, for others (some FPU instructions) default type does not exist (those
 instructions require precise type specification).

 Some  instructions  (LDS, LES, LSS, LFS, LGS, LGDT, LIDT, SGDT, SIDT)  allow
 6-byte arguments and thus FWORD type to be used in type casting. This applys
 to 386 instruction set. Other instruction sets like FPU, MMX, etc. use their
 own appropiate types DWORD, QWORD, TBYTE and OWORD/DQWORD. 



 15.8. Default segment change
 ----------------------------

 When referencing data (memory) it is possible to use  any  segment  register
 not just the default one. XAssembler uses special  prefixes  that  allow  to
 change default segment. Their usage  is  limited  only  to  references  with
 square brackets.

   mov al,  [es:bx]
   mov ebx, [fs: ofs data + 11h]

 The following prefixes are available : "cs:", "ds:", "es:", "ss:", "fs:" and
 "gs:" (which matches all available segment registers). The compiler requires
 that used prefix is placed as first in bracket.



 15.9. CALL, JMP and Jcc jump addressing
 ---------------------------------------

 XAssembler offers variety of methods to specify the target address in jumps.


 Addressing by name :

   call my_proc
   jmp  my_label
   jz   my_label

 The compiler allows jumps JMP/Jcc to procedures and calls CALL to labels. At
 compilation time when such references are recognized a warning is shown.


 Addressing by function :

   call ofs my_proc
   jmp  ofs my_label
   jz   ofs my_label

 Unlike in data references both addressing methods described above give equal
 results. Additionally,  addressing  by  function  allows  usage  of  numeric
 expression in address specification.

   call ofs my_proc + 2
   jmp  ofs my_label - 0Fh
   jz   ofs my_label - 4


 Addressing by register and memory :

   call eax
   call [bx]
   jmp  eax
   jmp  [bx]

 Conditional jumps can not be addressed this way.


 Indirect addressing :

   call @ - 3
   jmp  @ + 2
   jz   @

 In indirect addressing the @ character means the address of next instruction
 after the jump. It allows to  specify  the  jump  size  starting  from  that
 instructions. Additionally, XAssembler offers _ip (_eip) predefined constant
 specyfying the address of current instruction.

   jz @
   jz _eip

 Both instructions in the example above jump to the same address.


 Addressing with jump type selection (SHORT, NEAR, FAR) :

   call near my_proc
   call far my_proc
   jmp  short my_label
   jmp  near ofs my_label - 2
   jmp  far 0h:1234h *
   jz   short my_label
   jz   near my_label + 8

   * - Segment and offset are separated by ":".


 Addressing with offset type selection (only jumps NEAR and FAR) :

   call near dword 0F00h
   call far word 0:1234h *
   jmp  near word ofs my_label
   jmp  far dword _cseg:80000020h *

   * - Offset type is specified before actual value of the address.

 Far jumps are recognized only by the specified type. If no type is specified
 the jump is always assumed to be NEAR.



 ----------------------------------------------------------------------------
 16. Local directives (switches)
 ----------------------------------------------------------------------------

 XAssembler offers a set of local dirctives that allows more precise  control
 over generated code. Those directives behave according to "act from location
 place" rule and in most cases have opposite equivalents. That's why they can
 act on selected fragments of code.

 List of local directives.

 ----------------------------------------------------------------------------
  Directive       | Effect
 ----------------------------------------------------------------------------
  {16+}/{16-}     | enable/disable genereation of 16-bit code
  {32+}/{32-}     | enable/disable genereation of 32-bit code
  {aN}/{a-}       | enable/disable aligning to N bytes
  {c+}/{c-}       | enable/disable address auto-completion *
  {g+}/{g-}       | enable/disable aligning procedures and global labels
  {j-}            | disable start jump
  {l+}/{l-}       | enable/disable aligning local data and labels
  {o+}/{o-}       | enable/disable optimized instruction forms *
  {p+}/{p-}       | enable/disable aligning to paragraph (16 bytes)
  {r+}/{r-}       | enable/disable automatic RET insertion *
  {s-}            | disable segment initialization
  {t+}/{t-}       | enable/disable adaptive aligning *
  {z+}/{z-}       | enable/disable zero displacement removal *
 ----------------------------------------------------------------------------
  {386}           | limit instruction set to 386 only
  {fpu+}/{fpu-}   | enable/disable 387+ FPU instructions
  {486+}/{486-}   | enable/disable 486 instructions
  {pent+}/{pent-} | enable/disable Pentium instructions
  {x86}           | enable all instructions implemented in this version *
 ----------------------------------------------------------------------------

 * - Switches enabled by default.


 Switches {16-} and {32+}, similar to {16+} and {32-}, are  equivalent.  They
 have been added only for easier usage.

 Switches {a-} and {g-} set align factor to global value  defined  with ALIGN
 directive (0 if it wasn't used).

 Switch {c+}/{c-} allows compiler to auto-complete some  forms  of  addresses
 not supported directly by x86 architecture.

 Switch {j-} disables "JMP BEGIN" jump at the start of the code in modes Bin,
 Com and Flat.

 Switch {s-} disables DS and ES register initializing at the beginning of the
 program (where BEGIN directive is) in modes Small and Near.

 Switch {r+}/{r-} controls the RET instruction insertion in the place of  END
 directive in procedures, however it doesn't  affect  instructions  put  with
 EXIT directive.

 Switch {z+}/{z-} decides wheter zero displacements  will  be  ignored.  This
 only affects "[reg + displacement]" addressing forms, with the  excetpion of
 "[bp+0]/[ebp+0]".



 ----------------------------------------------------------------------------
 17. Including files
 ----------------------------------------------------------------------------

 The compiler allows to include additional source files.  This feature can be
 used to split "long" program into smaller parts. Also  it  makes  easier  to
 work on the program by  dividing  it  into  separate  modules  of  different
 functionality.

 Including files is done with INCLUDE directive.

   INCLUDE "file name"

 The included file name must be put into  apostrophes.  Similar  as  in  data
 definitions XAssembler allows to use single or double apostrophes under  the
 condition that the same type of apostrphe is used before and after the name.

 When loading files XAssembler looks for them in primary file  directory.  If
 the file can not be found, the compiler tries to search  "INC"  subdirectory
 in its own installation path.

 The INCLUDE directive can be also used inside the included files. Next files
 can be included up to 20 levels. It gives enough place even for  very  large
 programs.

 The INCLUDE directive can not be used in initial block, inside procedures or
 inside main unit. In other words every procedure and main  unit  must  begin
 and end in the same file.



 ----------------------------------------------------------------------------
 18. Inserting code
 ----------------------------------------------------------------------------

 XAssembler allows direst insertion of code into program source.  The  INLINE
 directive serves this purpose. The values following the directive correspond
 to the binary code bytes, which will be inserted into output file.

   INLINE byte1, byte2, byte3, ... , byteN

 The number of inserted  bytes  is  unlimited.  This  method  allows  to  use
 instructions not recognized by the compiler. The  INLINE  directive  can  be
 used only inside procedures and main unit.


 The second method is to use INSERT directive. It  allows  to  insert  bigger
 fragment of code from external file.

   INSERT "file name"

 The content of specified file will be used  to  generate  output  file.  The
 INSERT directive can be used anywhere within code block. Of course the  file
 name must be put into apostrophes.



 18.1. Segment incompatibility error
 -----------------------------------

 This problem applys only to INSERT directive and inserting fragments of code
 which depend on its location in segment. It may happen, that the segment  of
 inserted code will differ from the segment of created program - in best case
 it will cause incorrect program behaviour.

 The solution is to use aligning to paragraph  ({p+} switch)  and  far  calls
 (modes Small and Near) or, if possible, avoid such  situations  (modes  that
 create code images).



 ----------------------------------------------------------------------------
 19. 32-bit applications
 ----------------------------------------------------------------------------

 Since the version 3.01 XAssembler is able to create real 32-bit programs  by
 offering Flat compilation mode. Of course it is  still  possible  to  create
 small/medium size DPMI  applications  using  16-bit  modes  and  {32+}/{32-}
 switches (such example is in the "Demo" direcrtory).

 In addition, the Flat mode offers several target file formats.  The usage of
 different formats is discussed below.

 The 16-bit version of XAssembler limits the size of code generated  in  Flat
 mode to 64k.



 19.1. Code Images
 -----------------

 Binary images of 32-bit code can be  generated  using  MODE  directive  with
 mode name "flat".
 
   MODE flat

 This mode is similar to Bin mode but it uses 32-bit code setting as default.
 Thus all data/code references will use 32-bit pointers.  All  rules  of  Bin
 mode apply also in Flat mode. The compiler will put a JMP instruction at the
 beginning of the image unless {j-} switch is used.



 19.2. DPMI (DOS Protecred Mode Interface)
 -----------------------------------------

 XAssembler can create 32-bit programs that will work under  the  control  of
 DPMI host. This process is similar to pure Flat mode in that it will  create
 32-bit image. However the compiler will also generate 'loader'  code,  which
 will initiate DPMI session and jump directly to 32-bit user image.

 Program that uses DPMI format must start with the following MODE directive.

   MODE flat, dpmi

 The compiler will create an EXE file that can be run in DOS environment with
 DPMI host installed.


 The DPMI format allows usage of MEMORY directive. However it is important to
 remember that stack and heap declared with this directive must meet the same
 limits as for 16-bit DOS programs (64k for stack, 600000 bytes for heap).

 Default size for stack is 4096 bytes (4k). For heap it is  0  (same  as  for
 16-bit modes). Minimal stack size is 32 bytes, however it should not be used
 due to different requirements of DPMI hosts.

 The stack used by DPMI client is the same that  16-bit  loader  used  before
 jumping to 32-bit code. of course the application  may  allocate  new  stack
 that'll be greater in size than 64k.


 When using DPMI format provided by XAssembler the 32-bit user code is always
 loaded into conventional memory (below 1st MB).  Thus the size limit for the
 program size (code + data + stack + heap) is 600k.


 The DPMI  format  ensures  that  several  important  values  are  passed  in
 registers to user code. These are :

   EAX = 32-bit code base
   EBX = data selector
   ECX = initial ESP value, also starting address for heap
   EDX = PSP selector

 After entering user code the momory model is entirely flat which means  that
 CS = DS = ES = SS. FS and GS are zeroed. The DPMI format uses ORG value  8h,
 which can not be changed (the ORG directive is not allowed). Those  8  bytes
 contains instructions that  initialize  DS, ES, SS and ESP  registers.  This
 also means that the actual user code starts from address CS:8h.

 The "Demo" directory contains an example program with additional  commentary
 to the usage of DPMI format.



 ----------------------------------------------------------------------------
 20. Passing messages in program source
 ----------------------------------------------------------------------------

 XAssembler offers two directives that allow to  pass  massages  to  user  at
 compilation time - MSG and PROGRESS.

   MSG "message"

 The MSG Directive  simply  prints  given  message  and  the  PROGRESS  shows
 current position within source as "file / line".



 ----------------------------------------------------------------------------
 21. Forced compilation abort
 ----------------------------------------------------------------------------

 In certain situations it is necessary to stop the  compilation  for  example
 to avoid an error. In that case the STOP directive will help. After  it  the
 compiler immediately finishes  its  work  printing  short  message  "Stop!".
 Additionally an exitcode 255 is returned (see chapter 30).



 ----------------------------------------------------------------------------
 24. Program compilation
 ----------------------------------------------------------------------------

 In most cases the compilation of a program is done  by  starting  XAssembler
 with source file name as a parameter. The rest is up to the compiler.



 24.1. Starting the compiler
 ---------------------------

 Starting the compiler is very easy - write in command line  "XASM flie"  and
 press enter, that's all. Of course "file" is the source file of program that
 will be compiled. It is recommended that the current directory is  the  same
 in which the source files are located. Puting path into AUTOEXEC.BAT file to
 make it available from any directory is very helpful.



 24.2. Options
 -------------

 XAssembler offers variety of options that allows  control  over  compilation
 process, however none of them is able to modify the  source  or  change  the
 content of the output file (option "-x" is the exception here).


 When calling the options must be placed between the compiler name and source
 file name.

   xasm.exe -o1 -o2 ... -on source_file

 The source file name can be (but don't have to be) put into apostrophes. It
 allows to use long file names easily.

 Compiler options :

 "-c" - Disable symbol cache. This option disables compiler internal buffers.
        It should be used only in very rare cases, when the structure of  the
        source file does  not  allow  the  buffering  mechanism  to  function
        properly or even complicates its work. However, for most programs  it
        is recommended to leave caching enabled.

 "-v" - Verify source only. Xassembler does a complete compilation but do not
        write the output file.

 "-f" - Force LFN. This option forces the  compiler  to  use  Long File Names
        (use only if autodetection fails).

 "-g" - Disable LFN. This option forces the compiler to use old fashion  file
        names in 8.3 format (use only if autodetection fails).

 "-q" - Disable messages. The compiler does  not  displays any  messages  nor
        warnings.

 "-r" - Generate report. XAssembler generates report from  compilation  which
        in fact is a copy of all messages shown during compilation.

 "-m" - Create map. The map simply shows addresses of all objects defined in
        program after it'll be loaded into memory for execution.

 "-o" - Specify output file. This options allow to specify name of  the  file
        diffrent from the default, which will be used as output. The new name
        must be specified directly after the option.

 "-w" - Save output file to remote dir. The compiler will  write  the  output
        file to directore where the source file  is  located  independent  on
        current directory.

 "-e" - Use extarnal "command line" file. XAssembler  makes  it  possible  to
        avoid the limit of command line length by using separate  text  file.
        File name must be given directly after option. Of course the  content
        of specified file is nothing else but the content of command line.
        
 "-x" - Reduce EXE file size. This option allows to reduce the size of 16-bit
        EXE programs (mode Near). It may save up to 64k but it  requires  the
        global  data   to  be   defined  is  specified   order.   Simply  the
        non-initialized data must be defined at the end of data  block.  This
        and some features of EXE format allow to save  some  space  on  disk.
        This method was used with success in previous versions.

        The side effect is that the default initial value 0 is not guaranteed
        for non-initialized variables (see p. 5.3).

 "-p" - Show full paths in messages. XAssembler displays  full paths  (drive,
        directory and file name) in all messages.

 "-s" - Show program status. This options allow the user to  view  additional
        informations about compilation process sucgh as : source  file  name,
        mode, stack and heap, all memory used by the compiler and compilation
        time with precision up to 1ms.

 "-t" - Show additional statistics for current compiler session.

 "-?" - Help.

 "-i" - Additional information.



 ----------------------------------------------------------------------------
 26. Predefined constants
 ----------------------------------------------------------------------------

 XAssembler proveides a small set of predefined constants. They can  be  used
 as regular constants defined  with  SET  directive  except  for  conditional
 expressions.

  -----------------------------------------------
   Const  | Represented value
  -----------------------------------------------
   _mode  | compilation mode *
   _ver   | compiler version **
  -----------------------------------------------
   _bits  | generated code type ***
   _ip    | ip of current instruction
   _eip   | eip of current instruction
   _dtp   | current pointer in data definition
  -----------------------------------------------
   _cseg  | code segment
   _dseg  | data segment
   _sseg  | stack segment
   _hseg  | heap segment
  -----------------------------------------------
   _ssize | stack size
   _hsize | heap size
   _dsize | data size
   _csize | code size
   _msize | module size
  -----------------------------------------------

  *   - Mode numbers are :
          1 - Bin
          2 - Com
          3 - Small
          4 - Near
          5 - Flat

  **  - Version encoding is done in following way :

          bit 11   bit 0
          |            |
          AAAA BBBB CCCC

        where version number is A.BC (4 msb bits are cleared).
        For version 3.12 the value of _ver constant is 312h.
      
  *** - This constant equals to 16 or 32 accordingly to current code type
        (16-bit or 32-bit).


 Constants _cseg, _dseg, _sseg, _hseg, _size and _hsize can be used  only  in
 Small and Near modes.

 Constants _dsize and _csize can be used only in Near mode.


 Because of the method in which the compiler calculates values only constants
 _mode, _ver and _bits can be used in conditional expressions.



 Add-ons



 ----------------------------------------------------------------------------
 29. List of compiler options
 ----------------------------------------------------------------------------

 Option      Description
 --------------------------------------------
 -c          disable symbol cache
 -v          verify source only
 -f          force LFN support
 -d          disable LFN support
 -q          disable messages (quiet mode)
 -r          generate raport (log)
 -m          create map

 -o "file"   specify output file
 -w          save output file to remote dir
 -e "file"   use external "command line" file
 -x          reduce exe size
 -p          show full paths in messages
 -s          show program status
 -t          show extra statistics

 -?          help
 -i          additional information
 --------------------------------------------



 ----------------------------------------------------------------------------
 30. List of compiler directives
 ----------------------------------------------------------------------------

 ALIAS       ALIGN       BEGIN       COMMENT     DEF         DUP
 ELSE        ELSEIF      END         ENDC        ENDI        ENDIF
 ENDF        ENDM        ENDR        ENDW        EXIT        EXTERN
 FILE        FOR         FUNC        IF          IFDEF       IFNDEF
 INCLUDE     INLINE      INSERT      INVOKE      LABEL       LIBRARY
 LOCAL       MACRO       MEMORY      MODE        MODIFY      MSG
 ORG         PROC        PROGRESS    PUBLIC      REPEAT      SECTION
 SET         STOP        STRUC       TIMES       UNTIL       USE
 VAR         WHILE



 ----------------------------------------------------------------------------
 31. Error codes
 ----------------------------------------------------------------------------

 Error code is a value returned by compiler after it's finished its work. It
 can be used in bath files through ERRORLEVEL variable.

 Code       Description
 ----------------------------------------------------
  0         no error - compilation successfull :)

  1         bad compiler parameters
  2         not enough memory
  3         no 386
  4         no 32-bit DPMI server present
  5         inconsistent program parameters
  6         mode not implemented
  7         mode restrictions exceeded
  8         too many relocations

  9..10     - reserved -

  11        unable to read library/object
  12        invalid library/object format

  13        - reserved -

  14        unable to write target file
  15        unable to read source file
  16        unexpected end of file

  18..40    - reserved -

  51        reserved symbol name                
  52        symbol already defined
  53        unknown symbol reference
  54        invalid symbol reference
  55        invalid numeric expression
  56        invalid conditional expression
  57        type mismatch
  58        invalid address specification
  59        missing symbol name
  60        missing instruction argument
  61        invalid instruction argument
  62        value out of range
  63        expression too long
  64        far call/jump not allowed
  65        jump target out of range

  66..70    - reserved -

  71        directive not allowed
  73        instruction not allowed

  73..79    - reserved -

  80        syntax error
  81        repeat section not closed

  82..90    - reserved -

  91        data type not supported
  92        multidefinitions not implemented
  93        constant value not available
  94        function not implemented
  95        initialized arrays not implemented
  96        float numbers not implemented
  97        directive not implemented
  98        instruction not implemented
  99        numeric expressions not implemented

 100..252   - reserved -

 253        compiler emergency shutdown

 254        - reserved -

 255        shutdown on STOP directive
 ----------------------------------------------------

 Codes 6 i 91..99 will change in future versions.



 ----------------------------------------------------------------------------
 32. Xassembler in net
 ----------------------------------------------------------------------------

 Home page   : http://xasm.webpark.pl/xasm

 Zedd's page : http://xasm.webpark.pl

 ----------------------------------------------------------------------------
