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

     The XAssembler Compiler v3.12 (16-bit DOS) - Podrecznik Uzytkownika

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


 Spis Tresci
 -----------

 1. Wstep
 2. Co nowego w porownaniu z wersja 2.3?
 3. Skladnia XAssemblera
  3.1. Rozkazy i rejestry
  3.2. Kompatybilnosc z wersja 2.3
 4. Budowa programu
  4.1. Tryby kompilacji
  4.2. Format pliku wynikowego
  4.3. Stos i sterta
  4.4. Rozmieszczenie blokow
  4.5. Ustawianie adresu bazowego
  4.6. Wyrownywanie danych i kodu
  4.7. Ograniczanie zestawu instrukcji
  4.8. Symbole
  4.9. Komentarze
 5. Dane
  5.1. Typy
  5.2. Stale
  5.3. Zmienne
  5.4. Autowypelnianie
  5.5. Dane lokalne *
  5.6. Tworzenie plikow danych
  5.7. Struktury *
  5.8. Liczby zmiennoprzecinkowe
 6. Procedury
  6.1. Typy procedur
  6.2. Przerwania
  6.3. Parametry *
  6.4. Bezpieczne wyjscie z procedury
 7. Modul glowny
 8. Etykiety
 9. Funkcje
  9.1. Funkcja Ofs
  9.2. Funkcja TypeOf
  9.3. Funkcja SizeOf
  9.4. Funkcja High *
  9.5. Funkcja Low *
  9.6. Typ argumentu funkcji High i Low *
  9.7. Nakladanie funkcji *
 10. Wyrazenia liczbowe *
 11. Funkcje tymczasowe *
 12. Makra *
 13. Kompilacja warunkowa *
  13.1. Konstrukcja IF/ELSE/ELSEIF/ENDIF *
  13.2. Wyrazenia warunkowe *
  13.3. Dyrektywy warunkowe IFDEF i IFNDEF *
 14. Petle *
  14.1. Petla REPEAT/UNTIL *
  14.2. Petla FOR/ENDFOR *
  14.3. Petla WHILE/ENDWHILE *
  14.4. Zmienne tymczasowe *
 15. Odwolania do symboli
  15.1. Stale
  15.2. Zmienne
  15.3. Procedury i etykiety
  15.4. Makra *
  15.5. Funkcje tymczasowe *
  15.6. Odwolania "z kropka" *
  15.7. Adresowanie bezposrednie i nakladanie typu
  15.8. Zmiana domyslnego segmentu
  15.9. Adresowanie skokow CALL, JMP i Jcc
  15.10. Odwolania do zmiennych lokalnych i parametrow *
  15.11. Odwolania wyprzedzajace *
  15.12. Modyfikacja danych/kodu *
 16. Dyrektywy lokalne (przelaczniki)
 17. Wlaczanie plikow
 18. Wstawianie kodu
  18.1. Blad niezgodnosci segmentow
 19. Programy 32-bitowe
  19.1. Obrazy kodu
  19.2. DPMI (DOS Protected Mode Interface)
  19.3. Windows *
  19.4. Linux *
  19.5. Pliki obiektowe COFF, MSCOFF i ELF *
 20. Przekazywanie wiadomosci w zrodle programu
 21. Wymuszenie zatrzymania kompilacji
 22. Aliasy *
 23. Biblioteki i pliki obietkowe *
 24. Kompilacja programu
  24.1. Uruchamianie kompilatora
  24.2. Opcje
  24.3. Zglaszane bledy i ostrzezenia
 25. Optymalizacja programu
 26. Stale predefiniowane
 27. Przyklady
 28. Slowo koncowe

 Dodatki

 29. Zestawienie opcji kompilatora
 30. Lista dyrektyw kompilatora
 31. Kody bledow
 32. XAssembler w sieci

 * - Brak implementacji w tej wersji :(



 ----------------------------------------------------------------------------
 1. Wstep
 ----------------------------------------------------------------------------

 Witam wszystkich :-) Ten dokument wyjasnia  zasady  pisania  programow  przy
 uzyciu kompilatora XAssembler.  Budowa i dzialanie  komputera  PC  nie  jest
 przedmiotem tego tekstu niemniej posiadanie wiedzy o tych zagadnieniach jest
 conajmniej wskazane.

 Czym jest XAssembler?

 Program ten jest  kompilatorem  jezyka  asembler  procesorow z rodziny  x86,
 posiadajacym  wlasna  (nieco odmienna)  skladnie,  umozliwiajacym  tworzenie
 16-to i 32-bitowych aplikacji.

 Dokument ten zaklada, ze czytelnik posiada przynajmniej podstawowa wiedze ma
 temat procesorow x86, instrukcji, sposobow  adresowania  itd.  W  przeciwnym
 wypadku polecam przeczytanie porzadnej ksiazki  lub  dokumentacji  jednego z
 producentow procesorow, ktore latwo mozna znalezc w internecie :)



 ----------------------------------------------------------------------------
 2. Co nowego w porownaniu z wersja 2.3 ?
 ----------------------------------------------------------------------------

 Wiele rzeczy. Przede wszystkim jeden program zamiast dwoch.  Rozwiazanie  to
 wymusilo napisanie od  nowa  calego  kodu.  Nowy  kompilator  jest  szybszy,
 bardziej elastyczny i odporny na nieprzewidziane sytuacje - program  posiada
 wewnetrzny mechanizm kontrolny. Poprawiony zostal system raportowania bledow
 dzieki czemu nie trzeba juz sie  zastanawiac  co  oznacza  jakis  komunikat.
 Dodana obsluga dlugich nazw plikow pozwala  wygodnie  pracowac  w  systemach
 udostepniajacych  ta  funkcje.  Nie  ma  tez  ograniczenia  rozmiaru  plikow
 zrodlowych do 50k. Usprawniony zostal takze sam mechanizm odczytu plikow.

 Kompilator jest wielokrotnie szybszy od  poprzednikow.  Zoptymalizowany  pod
 wzgledem szybkosci analizator leksylkalny jest w stanie przetworzyc  do 3 MB
 kodu zrodlowego na sekunde !!! Skaner symboliczny korzysta przy wyszukiwaniu
 z mechanizmu sum kontrolnych. Dodatkowo zaimplementowany system  buforowania
 symboli przyspiesza przetwarzanie symboli.  Dzieki temu jest on kilkukrotnie
 wydajniejszy od swojego odpowiednika z poprzednich wersji programu. Wynikiem
 zastosowania tych rozwiazan jest srednia predkosc przetwarzania okolo  75000
 linii na sekunde dla typowego kodu zrodlowego.

 Jesli chodzi o skladnie to dodanych  zostalo  kilka  dyrektyw  ulatwiajacych
 kontrole nad procesem kompilacji i generowanym  kodem.  Znacznie  zwiekszone
 zostaly mozliwosci definiowania danych.

 Kompilator posiada wbudowany modul  obliczeniowy,  pozwalajacy  na  uzywanie
 skomplikowanych wyrazen liczbowych bezposrednio w kodzie programu. Dzialanie
 modulu jest praktycznie niezauwazalne - automatycznie dopasowuje sie  on  do
 uzytego typu danych pozwalajac jednoczesnie prowadzic  obliczenia  nawet  na
 wartosciach wykraczajacych poza zakres danego typu.

 XAssembler  udostepnia  wlasny  format  plikow  bibliotecznych  umozliwiajac
 tworzenie dowolnych zbiorow procedur i danych do wykorzystania w programach.



 ----------------------------------------------------------------------------
 3. Skladnia XAssemblera
 ----------------------------------------------------------------------------

 Kompilator akceptuje pliki zrodlowe bedace czystym tekstem (ze zwyklym  badz
 odwroconym znacznikiem konca linii) dowolnej dlugosci.

 Rozpoznawane  sa  liczby  zapisane  w  systemie  dziesietnym  ( calkowite  i
 rzeczywiste), dwojkowym oraz szesnastkowym.

 Kompilator odroznia liczby rzeczywiste po kropce, zapisane zarowno w notacji
 zwyklej jak i naukowej.

 Przyklady :

   10       liczba calkowita
   10.0     liczba rzeczywista
   1.0e1    liczba rzeczywista (notacja naukowa)

   1010b    liczba dwojkowa (litera "b" po)

   $A       liczba szesnastkowa (znak "$" przed)
   0Ah      liczba szesnastkowa (litera "h" po) *

 * - Przy zapisie z litera "h" liczba musi sie rozpoczynac od  cyfry  (litery
     "A".."F" nalezy poprzedzic zerem).


 Nazwy symboli moga zawierac litery, cyfry oraz znakiow "_", "@" i "?" (znaki
 "@" i "?" nie moga byc pierwszymi znakami nazwy). Ponadto nazwy nie moga sie
 zaczynac od  cyfry  inaczej  zostana  potraktowane  jak  liczby.  Maksymalna
 dlugosc nazwy wynosi 90 znakow.

 Znaczenie i forma instrukcji kodu maszynowego jest praktycznie  identyczna z
 powszechnie  przyjetym  standardem  Intela.   Roznice  wystepuja  jedynie  w
 przypadku  funkcji  kompilatora   oraz  sposobach  odwolania   do   pamieci.
 Zagadnienia te sa omowione w dalszej czesci dokumentacji.



 3.1. Rozkazy i rejestry
 -----------------------

 Instrukcje rozpoznawane przez kompilator (kolejno 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 (dodane dla zapewnienia kompatybilnosci)


  BSWAP, INVD, INVLPG, WBINVD


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


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

 Rejestry koprocesora :
  - ST0(ST),ST1,ST2,ST3,ST4,ST5,ST6,ST7.

 Rejestry segmentowe :
  - CS,DS,ES,SS,FS,GS.

 Rejestry kontrolne :
  - CR0,CR2,CR3,CR4.

 Rejestry debugowania :
  - DR0,DR1,DR2,DR3,DR4,DR5,DR6,DR7.



 3.2. Kompatybilnosc z wersja 2.3
 --------------------------------

 Przeczytaj to tylko jesli uzywales starej wersji :)

 Wobec zmiany niektorych zalozen dotyczacych budowy samego programu konieczna
 jest modyfikacja starych zrodel tak aby staly sie one zrozumiale  dla  nowej
 wersji kompilatora.

 Aby to osiagnac nalezy :
  - zastosowac tryb kompilacji Small lub Near (zob. punkt 4.1), *
  - zmienic zapis dyrektywy MEMORY (zob. punkt 4.3),
  - usunac dyrektywy VAR i CONST,
  - przy dyrektywach INCLUDE ujac nazwy plikow w apostrofy,
  - usunac dyrektywy INTERRUPT (zob. opis tworzenia przerwan w punkcie 6.2),
  - zamienic dyrektywy CODE na dyrektywe INLINE,
  - zamienic dyrektywe PROGRAM na dyrektywe BEGIN.

 * - Tryb Near jest jedynym trybem  w pelni  kompatybilnym  ze  stara  wersja
     kompilatora chociaz nie musi byc stosowany jezeli nie wymaga  tego  sama
     konstrukcja programu.
 
 Wersja 2.3 umozliwiala definiowanie wielu symboli o tej samej nazwie podczas
 gdy nowa wersja nie pozwala na takie definicje. Rozwiazaniem  tego  problemu
 jest zmiana wszystkich konfliktowych nazw.

 Za wyjatkiem powyzszych elementow kompilator jest calkowicie kompatybilny ze
 stara wersja; nie ma tu potrzeby zmian poszczegolnych instrukcji ani ogolnej
 konstrukcji programu.



 ----------------------------------------------------------------------------
 4. Budowa programu
 ----------------------------------------------------------------------------

 Typowy program xassemblerowy jest podzielony na  trzy  bloki  funkcjonalne :
 blok wstepny, blok danych, blok kodu.

 Blok wstepny zawiera informacje dotyczace :
  - trybu kompilacji (dyrektywa MODE),
  - rozmiaru stosu i sterty (dyrektywa MEMORY),
  - poczatku kodu (dyrektywa ORG),
  - wyrownywania (dyrektywa ALIGN),
  - uzywanych bibliotek/obiektow (dyrektywa USE),
  - skoku startowego ({j-}) lub inicjacji rejestrow DS/ES ({s-}).

 Blok danych zawiera :
  - stale (dyrektywa SET),
  - zmienne gobalne (derektywa DEF i dyrektywy pomocnicze),
  - aliasy (dyrektywa ALIAS).

 Blok kodu zawiera :
  - procedury (dyrektywa PROC/END),
  - modul gowny (dyrektywa BEGIN/END),
  - etykiety lokalne,
  - etykiety globalne (dyrektywa LABEL),
  - stale (dyrektywa SET),
  - zmienne lokalne (dyrektywy DEF i LOCAL).

 Dodatkowo w blokach danych i kodu dozwolone  sa  dyrektywy  INCLUDE,  MSG  i
 STOP. Pozostale dyrektywy maja zastosowanie w szczegolnych przypadkach i  sa
 opisane w dalszych rozdzialach.

 W kodzie zrodlowym  bloki  zawsze  ulozone  sa  sekwencyjnie  i  wystapienie
 dyrektywy nie nalezacej do danego bloku powoduje przejscie do nastepnego np.
 LABEL oznacza poczatek bloku kodu.

 Oczywiscie taki suchy opis nie wyjasnia wszystkiego czas wiec na przykladowy
 program.


   ; --- blok wstepny ---
   MODE com


   ; --- blok danych ---
   DEF tekst = 'XASM rulez :D',13,10,36


   ; --- blok kodu ---
   PROC print

     mov  ah, 9
     int  21h

   END

   ; --- modul glowny (nalezy do bloku kodu) ---
   BEGIN

     mov  dx, ofs tekst
     call print

     ret

   END


 Ze wzgledu na mozliwosc roznego traktowania zrodla programu przez kompilator
 zaden z wymienionych blokow nie jest obowiazkowy (najczesciej jednak program
 musi zawierac co najmniej blok kodu).



 4.1. Tryby kompilacji
 ---------------------

 XAssembler udostepnia piec trybow kompilacji. 

 Bin - najprostszy z trybow. Pozwala na generowanie jednosegmentowych (dane i
   kod znajduja sie w jednym segmencie) obrazow kodu  16-bitowego. Idealny do
   tworzenia boot-sektorow lub gotowych fragmentow kodu.
   Maksymalny rozmiar pliku : 64k.

 Com - taki sam jak Bin z tym, ze ma na stale  ustawiona  wartosc  ORG  100h.
   Sluzy wylacznie do tworzenia 16-bitowych programow  typu  COM.  Maksymalny
   rozmiar pliku : 64k - 256 (PSP) - 2 (slowo na stosie) = 65278 bajtow

 Small - podobny do  poprzednikow.  Generuje  16-bitowe  programy  typu  EXE.
   Maksymalny rozmiar pliku : 64k.

 Near - kod i dane znajduja sie w osobnych segmentach. Jedyny  tryb  w  pelni
   kompatybilny z wersja 2.3. Generuje 16-bitowe programy typu EXE.
   Maksymalny rozmiar pliku : 64 k (kod) + 64k (dane) = 128k (131072 bajty).

 Flat - 32-bitowy odpowiednik trybu Bin.  Pozwala  na  tworzenie  32-bitowych
   obrazow kodu. Przeznaczony do tworzenia aplikacji DPMI lub  programow  dla
   32-bitowych systemow operacyjnych.  Maksymalny  rozmiar  pliku  zalezy  od
   wybranego formatu pliku wynikowego (zob punkt 4.2).

 Wybrany tryb kompilacji okreslany jest w bloku wstepnym dyrektywa MODE.

   MODE nazwa_trybu

 Nazwy trybow to oczywiscie Bin, Com, Small, Near i Flat. Dyrektywa MODE musi
 byc umieszczona jako pierwsza w  kodzie  zrodlowym.  Przy  braku  okreslenia
 trybu kompilator przyjmuje domyslny tryb Com.


 Tryby tworzace 16-bitowe programy EXE nakladaja  dodatkowe  ograniczenie  na
 maksymalny  rozmiar  programu  (kod + dane + stos + sterta).   Nie  moze  on
 przekraczac  600  kilobajtow  (600k  =  614400 bajtow  =  38400 paragrafow).
 Wieksze aplikacje nie zostana zaladowane przez  DOS  z  powodu  ograniczenia
 rozmiaru pamieci w trybie rzeczywistym.



 4.2. Format pliku wynikowego
 ----------------------------

 Tryb Flat umozliwia dodatkowo wybranie formatu pliku wynikowego. Dostepne sa
 nastepujace formaty :

   dpmi   - plik wykonywalny (DOS, 32-bit)
   pe     - plik wykonywalny (Windows)
   coff   - plik obiektowy COFF (Common Object File Format)
   mscoff - odmiana formatu COFF wprowadzona przez Microsoft
   elf    - plik obiektowy ELF (Executable and Linkable Format)
   elfexe - plik wykonywalny (Linux)

 Wybor formatu okreslany jest dodatkowym parametrem dyrektywy MODE.

   MODE flat, format

 Oczywsicie, w przypadku braku okreslonego formatu kompilator generuje  obraz
 kodu. Wiecej o formatach plikow w rozdziale 19.



 4.3. Stos i sterta
 ------------------

 16-bitowe programy typu EXE wymagaja podania  rozmiaru  stosu  i  sterty,  z
 ktorych beda korzystac w trakcie dzialania. W programach tych  XASM  okresla
 domyslny rozmiar stosu na 1024 bajty zas sterty na 0.  Mozna  to  oczywiscie
 zmienic stosujac dyrektywe MEMORY.

   MEMORY rozmiar_stosu, rozmiar_sterty

 Oba rozmiary podaje sie w bajtach. Kod + dane + stos + sterta musza zmiescic
 sie w pamieci konwencjonalnej czyli okolo 600k, w przeciwnym wypadku  system
 nie uruchomi programu. Stad maksymalny  rozmiar  sterty  to  600000  bajtow.
 Minimalny rozmiar stosu to 16 bajtow.

 XAssembler udostepnia proste mechanizmy korzystania z zadeklarowanej  sterty
 poprzez predefina stala _hseg. Rozmiar sterty jest  dostepny  poprzez  stala
 _hsize.



 4.4. Rozmieszczenie blokow
 --------------------------

 Ulozenie blokow wzgledem siebie w kodzie zrodlowym odpowiada  ich  polozeniu
 po zaladowaniu programu do pamieci za wyjatkiem trybu Near  (w  ktorym  dane
 znajduja sie za  kodem) i trybu  Flat  (niektore  formaty  pliku  wynikowego
 pozwalaja na rozmieszczanie blokow w innej kolejnosci).  Lokalizacja  stosu,
 pomimo iz nie jest on faktycznie definiowany  w  programie,  okreslana  jest
 przez kompilator.

  ---------------------------------------------------
   Tryb                  | Ulozenie blokow w pamieci
  ---------------------------------------------------
   Bin, Com, Small, Flat | dane -> kod -> stos *
   Near                  | kod -> dane -> stos
  ---------------------------------------------------

  * - Poza trybem Small rozmiar i polozenie stosu na etapie kompilacji nie
      jest znane.



 4.5. Ustawianie adresu bazowego
 -------------------------------

 Tryby generujace obrazy kodu (Bin i Flat) pozwalaja na wybor adresu bazowego
 obrazu - adresu, pod ktory zostanie on zaladowany. Sluzy do  tego  dyrektywa
 ORG.

   ORG adres_bazowy

 Wybrana wartosc adresu bazowego nie moze byc  ona  wieksza  od  maksymalnego
 rozmiaru okreslonego dla danego trybu, musi tez wystarczyc na  pomieszczenie
 obrazu w segmencie.

 Tryb Com, rowniez generujacy obraz kodu, ma staly adres bazowy rowny 100h.



 4.6. Wyrownywanie danych i kodu
 -------------------------------

 Operacja wyrownywania ma  za  zadanie  przyspieszyc  dzialanie  programu a w
 niektorych przypadkach jest  wrecz  wymagana  np.  przez  uzyte  instrukcje.
 Wyrownywanie polega na  takim  rozmieszczeniu  elementow  programu  aby  ich
 adresy byly podzielne przez okreslona liczbe bez reszty.

 Do wyrownywania sluzy  dyrektywa  ALIGN.  Pozwala  ona  zdefiniowac  wartosc
 wyrownywania dla calego programu - wyrownywanie globalne. Dozwolone wartosci
 to 2,4,8 i 16. W praktyce stosowanie wartosci 8 i 16 nalezy ograniczyc tylko
 do miejsc, w ktorych jest to konieczne gdyz zwieksza  to  znacznie  wynikowy
 rozmiar programu. 

   ALIGN 2

 Domyslnie wyrownywaniu podlegaja tylko dane  globalne.  Procedury,  etykiety
 globalne oraz dane i etykiety lokalne takze moga zostac poddane tej operacji
 o ile zostal  uzyty  przelacznik {g+} lub {l+} (zob.  rozdzial  16),  nalezy
 jednak pamietac, ze zwieksza to znacznie rozmiar kodu.

 Jesli chodzi o zmienne typow podstawowych  (patrz punkt 5.2)  to  XAssembler
 stosuje tzw.  wyrownywanie  adaptywne. W skrocie oznacza to, ze wyrownywaniu
 nie podlegaja zmienne o rozmiarze mniejszym niz podana  wartosc,  ktore  nie
 wykraczaja poza granice wyrownywania. Oczywiscie mozna ta  funkcje  wylaczyc
 przelacznikiem {t-}, wtedy kazda zmienna zostanie wyrownana.

 Kompilator umozliwia tez stosowanie wyrownywania dla  okreslonego  fragmentu
 programu. Wiecej o tym w rozdziale 15.



 4.7. Ograniczanie zestawu instrukcji
 ------------------------------------

 XAssembler  umozliwa  pelna  kontrole  nad  dostepnoscia  zaimplementowanych
 instrukcji na podstawie klasy procesora, w ktorym zostaly  one  wprowadzone.
 Minimalny dostepny zestaw instrukcji to  386.  Nowsze  instrukcje  moga  byc
 dowolnie dodawane lub usuwane  niezaleznie  od  klasy  procesora  do  ktorej
 naleza. Szczegoly w rozdziale 16.



 4.8. Symbole
 ------------

 Dla XAssemblera "symbol" oznacza ciag znakow  przypisany  danemu  elementowi
 programu, do ktorego mozna sie odwolywac. Poniewaz  odwolania  te  moga  byc
 rozne niezaleznie od rodzaju danego elementu,  w komunikacji z uzytkownikiem
 stosowane jest wlasnie to okreslenie. Nalezy jednak pamietac, ze odnosi  sie
 ono zarowno do stalej, zmiennej, procedury jak i etykiety.



 4.9. Komentarze
 ---------------

 Mozliwosc umieszczania komentarzy w kodzie zrodlowym  programu  jest  bardzo
 wazna  gdyz ulatwia pozniejsze jego zrozumienie.  Komentarze  pozwalaja  tez
 wylaczyc dowolny fragment kodu z programu. XAssembler rozpoznaje  komentarze
 po sredniku. Wszystko po tym znaku jest ignorowane az  do  napotkania  konca
 linii.

   mov ax, 1    ; komentarz do konca linii


 Kompilator umozliwia takze obejmowanie wiekszego fragmentu  kodu  zrodlowego
 jako komentarze za pomoca dyrektywy COMMENT/ENDC.

   mov ax, 1

   COMMENT

     dowolna zawartosc ignorowana przez kompilator

   ENDC

   mov dx, 1


 Komentarze ze srednikiem sa  obslugiwane  juz  na  etapie  wczytywania  kodu
 zrodlowego mozna je wiec stosowac w dowolnym miejscu programu.



 ----------------------------------------------------------------------------
 5. Dane
 ----------------------------------------------------------------------------

 XAssembler umozliwia definiowanie praktycznie dowolnego  rodzaju  danych.  W
 przeciwienstwie do wersji 2.x same definicje sa znacznie prostsze i bardziej
 wygodniejsze w uzyciu.



 5.1. Typy podstawowe
 --------------------

 XAssembler udostepnia 7 typow podstawowych. Ponizsza  tabela  charakteryzuje
 poszczegolne typy i ich wlasciwosci.

  ----------------------------------------------------------------------
   typ    | bajtow | zakres wartosci (ze znakiem)  | uwagi
  ----------------------------------------------------------------------
   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   | jak wyzej                     | alternatywna nazwa
  ----------------------------------------------------------------------

  * - Odpowiedniki typow rzeczywistych jezykow wysokiego poziomu.



 5.2. Stale
 ----------

 Stale w XAssemblerze reprezentuja konkretna wartosc liczbowa  i  jako  takie
 nie sa wlaczane do pliku wynikowego. Do definiowania stalych sluzy dyrektywa
 SET.

   SET nazwa_stalej = wartosc_stalej

 Wartosc stalej moze byc liczba lub wyrazeniem liczbowym - wyrazenie nie moze
 zawierac odwolan "w przod".

 Z oczywistych wzgledow rozroznia sie stale calkowite i rzeczywiste.

   SET a = 10     ; stala calkowita
   SET b = 10.0   ; stala rzeczywista *

   * - zob. punkt 5.8

 Niezaleznie od rodzaju stalej reprezentuje ona jakas wartosc, ktora moze byc
 pozniej uzyta w dowolnym miejscu programu.

 Definicje stalych moga sie znajdowac w dowolnym  bloku  programu  przy  czym
 nalezy pamietac, ze mimo globalnosci kazda stala jest  widoczna  dopiero  od
 miejsca definicji.



 5.3. Zmienne
 ------------

 Zmiennymi w XAssemblerze sa dane, ktore program moze swobodnie modyfikowac w
 dowolnym momencie wykonania. Do definiowania zmiennych sluzy dyrektywa  DEF.
 Wyroznia sie dwa rodzaje zmiennych : zmienne beztypowe  oraz  zmienne  typow
 podstawowych.


 Zmienne beztypowe pozwalaja na definiowanie dowolnych ciagow  znakow i liczb
 bez okreslania ich typu (domyslnie wszystkie elementy  takiego  lancucha  to
 bajty).

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

 Dodatkowo kompilator umozliwia nadawanie roznego  typu  kazdemu elementowi i
 tworzenie przez to zmiennych mieszanych.

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

 Kolejnym atutem zmiennych beztypowych jest mozliwosc  korzystania  z  plikow
 zewnetrznych jako zrodel danych. Sluzy do tego dyrektywa FILE.

   DEF font = FILE "myfont.dat"


 Zmienne typow podstawowych posiadaja jednoznacznie  okreslony  typ.  Sa  one
 przeznaczone do tworzenia  pojedynczych  zmiennych  lub  tablic  o  dowolnej
 dlugosci.

   DEF data : BYTE
   DEF tab  : [10]           ; tablica 10 bajtow
   DEF tab2 : DWORD [4]      ; tablica 4 podwojnych slow

 Zmienne takie moga byc  nie zainicjowane  (jak w powyzszym przykladzie)  lub
 zainicjowane. Nadawanie wartosci odbywa sie w ten sam sposob jak w przypadku
 zmiennych beztypowych.

   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

 Zmienne pojedyncze mozna rozwijac do tablic o dowolnej ilosci elementow  bez
 wpisywania wartosci w nawiasie kwadratowym  (zob. druga  linia  w  powyzszym
 przykladzie).

 Kompilator gwarantuje wartosc 0 dla zmiennych niezainicjowanych .  Wyjatkiem
 od tej reguly sa dwa przypadki :
  - uzycie opcji "-x" w trybie Near (zob. rozdzial 23),
  - skorzystanie z wlasnosci trybu Flat - dodatkowe formaty plikow wynikowych
    pozwalaja na definicje danych nie zainicjowanych w sekcji .bss, ktorych
    zawartosc na etapie kompilacji nie jest okreslona.


 Zarowno zmienne beztypowa jak i zmienne typow podstawowych  umozliwiaja  tak
 zwane multi-definicje. W ten sposob wiecej niz  jedna  zmienna  moze  zostac
 utworzona w pojedynczej definicji.

   DEF a,b,c : WORD



 5.4. Autowypelnianie
 --------------------

 Funkcja autowypelniania pozwala  na  szybkie  definicje  powtarzajacych  sie
 ciagow danych.  Sluza  do  tego  dyrektywy  REPEAT  i  TIMES  (zmienne typow
 podstawowych  i  zmienne  mieszane)  oraz  dyrektywa  DUP  (tylko  tablice).
 Korzystajac z autowypelniania trzeba  pamietac,  ze  blokuje  ono  mozliwosc
 stosowania odwolan w przod. Ponadto nalezy zachowac typ nadany w  definicji.
 Dodatkowo stala _dtp (zob. rozdzial 26) nie jest aktualizowana  dla  kazdego
 powtorzenia.

 Autowypelnianie w definicjach zmiennych nie-tablicowych  mozna  wykonywac  w
 dwojaki  sposob  uzywajac  samej  dyrektywy  TIMES  lub  tez  pary  dyrektyw
 REPEAT/TIMES. Mozna dzieki temu powtarzac dowolna  czesc  definicji.  Ogolna
 postac definicji wyglada nastepujaco :

   DEF nazwa = element_powtarzany TIMES licznik_powtorzen
   DEF nazwa = REPAT el1,el2,...,elN TIMES licznik_powtorzen

 Jak widac element(y) powtarzany(e) znajduje sie przed  dyrektywa  TIMES  zas
 licznik powtorzen po dyrektywie. Sama wartosc licznika  powtorzen  moze  byc
 wyrazeniem liczbowym. Ponizszy przyklad zawiera  definicje z  wykorzystaniem
 dyrektyw REPEAT i TIMES oraz ich odpowiedniki w rozwinieciu.

   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

 Dyrektywe TIMES lub pare dyrektyw REPEAT/TIMES mozna stosowac wielokrotnie w
 obrebie tej samej definicji.


 Autowypelnianie w tablicach zainicjowanych za pomoca dyrektywy DUP rozni sie
 znacznie od przypadku  opisanego  powyzej .  Tutaj  nie  mamy  juz  licznika
 powtorzen gdyz nie jest on potrzebny (kompilator  sam  wypelnia  tablica  do
 jej rozmiaru podanego wczesniej w definicji) a powtarzane elementy  znajduja
 sie po dyrektywie. Oto ogolna postac takiej definicji :

   DEF nazwa : typ [rozmiar] = DUP element_powtarzany
   DEF nazwa : typ [rozmiar] = DUP el1,el2,...,elN

 Powtarzac mozna pojedynczy element  lub  dowolna  ich  ilosc - ograniczeniem
 jest tylko rozmiar tablicy. XAssembler dopuszcza takze mozliwosc uprzedniego
 zdefiniowania czesci tablicy zwykla metoda i  pozniejszego  dopelnienia  jej
 dyrektywa DUP.

   DEF nazwa : typ [rozmiar] = el1,el2, DUP element_powtarzany
   DEF nazwa : typ [rozmiar] = el1,el2, DUP el3,el4,...,el5

 Ponizsze przyklady demonstruja definicje z uzyciem dyrektywy  DUP  oraz  ich
 odpowiedniki w rozwinieciu.

   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. Tworzenie plikow danych
 ----------------------------

 Jednym z dodatkowych zastosowan  XAssemblera, dosc  daleko  odbiegajacym  od
 programowania jest mozliwosc tworzenia plikow dowolnych  danych.  Mozliwosci
 takie daja tryby Bin i Flat, ktore dopuszczaja mozliwosc  calkowitego  braku
 kodu w programie. Wzor takiego "programu" wyglada nastepujaco.

   MODE bin    ; lub flat
   {j-}        ; blokada skoku startowego

   ; definicje danych, z ktorych powstawnie plik

   END

 Uruchomienie kompilatora z nazwa pliku jako  jedynym  parametrem  wygeneruje
 plik binarny z odpowiednia zawartoscia. Wybor trybu  nie  powinien  stwarzac
 problemow. Dla plikow mniejszych niz 64k nadaje sie tryb Bin, dla  wiekszych
 tryb Flat. Oba tryby nieco sie  roznia  pod  wzgledem  dzialania  niektorych
 funkcji co takze trzeba wziac pod uwage.



 5.8. Liczby zmiennoprzecinkowe
 ------------------------------

 XAssembler rozroznia dwa rodzaje liczb zmiennoprzecinkowych:
  - single (32 bity, typ DWORD, do 8 cyfr znaczacych),
  - double (64 bity, typ QWORD, do 15 cyfr znaczacych).

 W plikach zrodlowych uwzgledniana jest dlugosc czesci calkowitej do 15  cyfr
 zas dlugosc  czesci  ulamkowej  do  20  cyfr.  Przekroczenie  tych  dlugosci
 spowoduje blad (w przypadku czesci calkowitej) lub pominiecie reszty cyfr (w
 przypadku ulamka). Calkowita  dlugosc  ciagu  znakow reprezentujacego liczbe
 zmiennoprzecinkowa nie moze przekroczyc 90 znakow.

 XAssembler umozliwia stosowanie  liczb  zmiennoprzecinkowych  w  definicjach
 stalych, zmiennych oraz w argumentach instrukcji. Ze wzgledu swoja specyfike
 tego rodzaju liczby wymuszaja stosowanie wylacznie typu DWORD lub QWORD (ten
 ostatni dozwolony jest tylko w definicjach danych).

 Jesli chodzi o stale to nalezy pamietac, iz nie posiadaja one nadanego typu,
 zas kompilator dopasowuje ich  wartosc  do  typu  obowiazujacego  w  miejscu
 odwolania  do  stalej.  Stad  tez  wynika  ograniczenie   stosowania   liczb
 zmiennoprzecinkowych w definicjach stalych do typu DWORD. Dodatkowy  problem
 pojawia sie przy stalej o wartosci '0.0'. W takim przypadku wyswietlane jest
 ostrzezenie gdyz na dalszym etapie kompilacji nie jest mozliwe  rozroznienie
 pomiedzy liczba zmiennoprzecinkowa '0.0' a liczba calkowita o wartosci 0, co
 moze powodowac np. bledne przypisanie wartosci '0.0' do zmiennej typu BYTE.


 Przyklady stosowania liczb zmiennoprzecinkowych.

   SET pi = 3.1415            ; definicja stalej (automatycznie typ DWORD)

   DEF alfa : dword = 0.01    ; definicja zmiennej typu DWORD
   DEF beta = qword -1.27     ; definicja zmiennej z wymuszeniem typu QWORD

   push dword 1.5             ; uzycie liczbe z-p bezposrednio w argumencie
                              ; instrukcji (tylko typ DWORD)


 Kodowanie liczb zmiennoprzecinkowych odbywa  sie  wg.  standardu  IEEE-754,
 ktory stosowany jest w koprocesorach z rodziny x87.



 ----------------------------------------------------------------------------
 6. Procedury
 ----------------------------------------------------------------------------

 Procedura jest wyodrebnionym fragmentem kodu, ktory  moze  byc  wielokrotnie
 wywolywany i wykonywany. Tresc procedury zawiera  sie  pomiedzy  dyrektywami
 PROC i END.

   PROC nazwa_procedury

   ; tresc procedury ...

   END

 W miejsce dyrektywy END kompilator automatycznie wstawia rozkaz  RET,  chyba
 ze zostala uzyta dyrektywa ENDR lub przelacznik {r-} (zob. rozdzial 15).



 6.1. Typy procedur
 ------------------

 XAssembler rozroznia tylko procedury typu NEAR. Wynika to z jednosegmentowej
 konstrukcji programow, w ktorych dostep do kazdej procedury zapewniaja tylko
 tego typu odwolania.

 Oczywiscie mozliwe jest utworzene procedury typu FAR. W tym  celu  wystarczy
 dyrektywe END zastapic przez ENDR oraz zastowsowac rozkaz RETF.



 6.2. Przerwania
 ---------------

 Tworzenie procedur obslugi przerwan jest proste. XAssembler  udostepnia  dwa
 sposoby.


 Pierwszym jest uzycie z  dyrektywy  ENDI  zamiast  END  (kompilator  wstawia
 rozkaz IRET/IRETD zaleznie od aktualnego rodzaju kodu).

   PROC przerwanie_1

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


 Drugim sposobem jest uzycie dyrektywy ENDR (lub przelacznika {r-}) i  reczne
 wstawienie rozkazu IRET/IRETD.

   PROC przerwanie_2

   iret    ; lub IRETD

   ENDR    ; dyrektywa ENDR nie wstawia instrukcji RET

 

 6.4. Bezpieczne wyjscie z procedury
 -----------------------------------

 XAssembler udostepnia  dyrektywe  EXIT  umozliwiajaca  bezpieczne  wyjscie z
 procedury niezaleznie od jej parametrow czy zmiennych lokalnych.  Ma  to  za
 zadanie ulatwic tworzenie kodu procedur.

   PROC moja_procka

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

     EXIT             ; <- rozkaz RET

   set_flag:
     mov [ebx], 1

   END                ; <- rozkaz RET

 Stosowanie tej metody nie jest konieczne ale znacznie poprawia przejrzystosc
 kodu  zrodlowego.  Oczywiscie  dyrektywa  EXIT  nie  moze  byc  stosowana  w
 procedurach wywolywanych jako FAR z wiadomych wzgledow (rozkaz  RET  zdejmie
 ze stosu tylko polowe adresu).



 ----------------------------------------------------------------------------
 7. Modul glowny
 ----------------------------------------------------------------------------

 Modul glowny zawiera kod, ktory bedzie wykonany bezposrednio po uruchomieniu
 programu. Zawiera sie on pomiedzy dyrektywami BEGIN i END. W  zaleznosci  od
 wybranego trybu kompilacji, dyrektywa BEGIN moze ukrywac pod soba  dodatkowe
 instrukcje.


 W trybach generujacych obrazy (Bin, Com i Flat) kompilator sam automatycznie
 wstawia na poczatek kodu skok do miejsca okreslonego dyrektywa BEGIN.

   jmp dyrektywa_begin   --
                           |
                           |
     ; definicje danych    |
                           |
     ; procedury           |
                           |
                           |
   BEGIN                 <-

   END

 W przypadku braku danych i procedur przed modulem  mozna  uzyc  przelacznika
 {j-} w celu pominiecia dodatkowej instrukcji JMP (zob. rodzial 15).


 W trybach Small i Near (16-bitowe programy typu EXE)  adres  punktu  wejscia
 jest okreslony w naglowku  pliku  wykonywalnego.  Program  musi  jednak  sam
 ustawic wartosc rejestru DS aby moc korzystac ze swoich danych.  Wobec  tego
 XAssembler wstawia automatycznie  instrukcje  inicjujace  segmenty DS i ES w
 miejsce dyrektywy BEGIN. W zaleznosci od trybu uzywane sa  rozne  kombinacje
 instruckji.

 Tryb Small (4 dodatkowe bajty) :

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

 Tryb Near (6 dodatkowych bajtow) :

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

 Podobnie jak w poprzednim przypadku kompilator  udostepnia przelacznik  {s-}
 pozwalajacy na rezygnacje z przedstawionych powyzej  instrukcji.  Przy  jego
 uzyciu nalezy jednak pamietac o wartosci DS nie wskazujacej na  zdefiniowane
 dane.


 XAssembler nie wstawia zadnych  instrukcji  konczacych  dzialanie  programu.
 W przypadku ich braku procesor bedzie traktowal znajdujace sie  dalej  bajty
 jako instrukcje i kontynuowal wykonywanie  programu.  Programista  sam  musi
 zadbac o zakonczenie aplikacji odpowiednio dla jej typu.



 ----------------------------------------------------------------------------
 8. Etykiety
 ----------------------------------------------------------------------------

 Etykiety bezposrednio okreslaja adres w segmencie kodu programu, do  ktorego
 za ich pomoca mozna sie odwolac. XAssembler rozroznia dwa rodzaje etykiet.

 Etykiety globalne, definiowane dyrektywa LABEL. Moga  one  znajdowac  sie  w
 dowolnym miejscu kodu  (wenwatrz i na zewnatrz procedur/modulu glownego) i z
 kazdego miejsca mozna sie do nich odwolac.

   LABEL nazwa_etykiety

   BEGIN

     LABEL nazwa_etykiety2

   END


 Etykiety lokalne  wystepuja  tylko  wewnatrz  procedur/modulu glownego.  Ich
 dostepnosc jest ograniczona  wylacznie  do  bloku  kodu,  w  ktorym  zostaly
 zdefiniowane. Definicja etykiety lokalnej nie wymaga uzycia zadnej dyrektywy
 a jedynie umieszczenia znaku ":" bezposrednio po nazwie etykiety.

   BEGIN

     nazwa_etykiety:

   END



 ----------------------------------------------------------------------------
 9. Funkcje
 ----------------------------------------------------------------------------

 XAssembler udostepnia szereg fukncji,  ktorych argumentami sa nazwy symboli,
 pozwalajacych na latwiejsze tworzenie programow. Zaleta funkcji jest to,  ze
 zwracane przez nie wartosci moga byc traktowane jako stale - nie  obowiazuja
 ich zasady zachowania zgodnosci typu. Wyjatkiem sa  tu  funkcje  Low i High,
 ktorych dzialanie jest scisle zwiazane z typem warosci docelowej.



 9.2. Funkcja Ofs
 ----------------

 Funkcja Ofs zwraca adres symbolu w odpowiadajacym mu segmencie, tzw. offset.
 Najczesciej wykorzystywana jest ona przy odwolaniach do danych przez  nawias
 kwadratowy oraz przekazywaniu parametrow do funkcji systemowych.

   DEF txt = 'hey!$'

   mov  ah, 9
   mov  dx, ofs txt                ; adres tekstu do wyswietlenia
   int  21h


   DEF data : WORD [100]

   mov  byte [ofs data], 0         ; bajt pierwszego slowa = 0
   mov  byte [ofs data + 100], 2   ; bajt piecdziesiatego slowa = 2


   PROC moja_procka
     add al, bl                    ; instrukcja zajmuje 2 bajty
     add al, cl
   END

   call ofs moja_procka + 2        ; wywolanie procedury z pominieciem
                                   ; pierwszej instrukcji

 Oczywiscie zastosowan tej fukncji jest znacznie wiecej co widac w ostatnim z
 przykladow.



 9.3. Funkcja TypeOf
 -------------------

 Funkcja zwraca typ symbolu. Argumentami moga byc zmienne  globalne,  lokalne
 oraz parametry procedur.

 -------------------------------------------
  Rodzaj symbolu   | Typ          | Wartosc
 -------------------------------------------
  Zmienna/Parametr | BYTE         |   201
                   | WORD         |   202
                   | DWORD        |   204
                   | FWORD        |   206
                   | QWORD        |   208
                   | TBYTE        |   210
                   | OWORD/DQWORD |   216
 -------------------------------------------

 Wartosci zwracane przez  funkcje  TypeOf  odpowiadaja  wartosciom  uzywanym
 wewnetrznie przez kompilator.



 9.4. Funkcja SizeOf
 -------------------

 Funkcja zwraca rozmiar symbolu  w  bajtach.  Argumentami  moga  byc  zmienne
 globalne, lokalne oraz parametry procedur.

   DEF txt = "The XAssembler Compiler",0

   mov eax, SizeOf txt   ; eax = 24



 ----------------------------------------------------------------------------
 15. Odwolania do symboli
 ----------------------------------------------------------------------------

 XAssembler udostepnia dwa podstawowe sposoby odwolan do symboli,  przy  czym
 kazdy z nich posiada specyficzne wlasciwosci.

 Pierwszym sposobem sa odwolania przez nazwe. Stosowana  w  nich  jest  tylko
 nazwa symbolu. Sa to odwolania najprostsze, wymagaja jednak pelnej zgodnosci
 typow w argumentach instrukcji.

 Drugim sposobem sa odwolania przez fukncje, w ktorych oprocz  nazwy  symbolu
 wystepuje takze jedna z funkcji (zob. rozdzial 9). W odwolaniach takich  nie
 jest sprawdzana zgodnosc typu a jedynie czy zwrocona wartosc  miesci  sie  w
 wymaganym zakresie.


 15.1. Stale
 -----------

 XAssembler umozliwia odwolania do stalych wylacznie przez nazwe. Odnosi  sie
 to zarowno  do  stalych  zdefiniowanych  dyrektywa  SET  jak  i  konkretnych
 wartosci liczbowych.

   SET count = 100

   mov  al, count
   mov  al, 100

 Dostepna jest takze trzecia forma stalych. Sa to stale  tekstowe,  stosowane
 bezposrednio w argumentach instrukcji.  Stale  te  maja  postac  lancucha  o
 dlugosci 1 do 4 znakow. Kompilator zamienia je na odpowiadajace im wartosci.
 Ponizsze instrukcje sa jednoznaczne.

   mov  al, 'A'
   mov  al, 65

 Wartosc stalej jest  automatycznie  dopasowywana  do  uzytego  typu  danych.
 Brakujace bajty sa zawsze zerowane. Kolejnosc znakow  w  lancuchu  odpowiada
 rzeczywistemu poloznieu bajtow w pamieci przy wykonaniu programu.

   mov dword [0], 'XASM'  ; do pamieci zostanie wpisany lancuch 'XASM'



 15.2. Zmienne
 -------------

 W odwolaniach przez nazwe  musi  byc  zachowany  typ  w  przeciwnym  wypadku
 kompilator wyswietli komunikat o  bledzie  "Type mismatch".  Z  tego  powodu
 zmienne beztypowe nie sa dostepne w takich odwolaniach.

   DEF a : BYTE
   DEF b : WORD

   mov  al, a         ; wartosc a zostanie zaladowana do al
   mov  dx, b         ; wartosc b zostanie zaladowana do dx


 W odwolaniach przez funkcje sprawdzany jest tylko zakres wartosci, tak  wiec
 w ponizszym przykladzie  jesli  Ofs txt < 256  to  ostatnia  linia  zostanie
 skompilowana poprawnie (bo al=0..255).

   DEF txt = 'XASM rulez!',0

   mov eax, ofs txt   ; adres txt zostanie zaladowany do eax
   mov ax,  ofs txt   ; ... ax
   mov al,  ofs txt   ; ... al



 15.3. Procedury i etykiety
 --------------------------

 W praktyce odwolania do procedur i etykiet nie roznia sie niczym od  odwolan
 do danych poza tym, ze odnosza sie do innego segmentu. Podstawowe zasady  sa
 takie same. Oczywisice w odwolaniach takich stosowane moga byc tylko rozkazy
 skokow.

   PROC moja_procka
   END

   BEGIN

   etykieta:

     call moja_procka
     call ofs moja_procka

     jmp  etykieta

   END



 15.7. Adresowanie bezposrednie i nakladanie typu
 ------------------------------------------------

 Przy omowionych wczesniej odwolaniach zawsze stosowana  byla  nazwa  symbolu
 zas obliczenie adresu nalezalo do kompilatora. Inaczej jest przy adresowaniu
 bezposrednim, w ktorym programista sam okresla adres wykorzystujac  zapis  w 
 nawiasie kwadratowym. Pozwala to na uzycie dowolnej kombinacji adresowej  ze
 wszystkich udostepnianych  przez  procesor.  XAssembler  umozliwia  uzywanie
 odwolan do symboli przez funkcje w specyfikacji  adresu.  Dodatkowo,  uzycie
 samej nazwy symbolu jest rownoznaczne z zastosowaniem  funkcji Ofs.  Oznacza
 to, ze zapis "[data]" jest rownoznaczny z zapisem "[ofs data]".

 Postac adresu zalezy od generowanego kodu: [BAZA + INDEKS + OFFSET] dla kodu
 16-bit lub [BAZA + INDEKS*SKALA + OFFSET] dla  kodu  32-bit.  Dokladny  opis
 mozna znalezc w dokumentacji procesorow x86.

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

 Sformulowanie "adresowanie bezposrednie" nie ma  nic  wspolnego  z  terminem
 stosowanym w dokumentacji procesorow x86. Wskazuje  ono  jedynie  na  sposob
 okreslania adresu w kodzie zrodlowym.


 Dodatkowa zaleta  adresowania  bezposredniego  jest  mozliwosc  wyboru  typu
 przesuniecia uzytego w adresie a przez to daje wieksza kontrole nad kodem.

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

 Dozwolone typy przesuniec to  BYTE,  WORD  i  DWORD.  Okreslenie  typu  moze
 wystepowac  w  dowolnym  miejscu  wewnatrz  nawiasu,  powinno   jednak   byc
 umieszczone przed wartoscia przesuniecia  w  celu  zachowania  zrozumialosci
 kodu.


 Nakladanie typu danych jest operacja  stosowana  w  instrukcjach, w  ktorych
 argumentem jest  pamiec.  Przy  braku  okreslenia  typu  kompilator  stosuje
 odpowiedni typ domyslny (o ile jest to mozliwe).

   mov [bx], 1         ; typ domyslny BYTE
   mov word [bx], 1    ; nalozenie typu WORD

 Nalezy pamietac, ze typ domyslny zmienia sie dla roznych instrukcji, np. dla
 instrukcji PUSH/POP jest to WORD lub DWORD w zaleznosci od rodzaju kodu, zas
 dla innych, np. niektorych instrukcji FPU, typ domyslny w ogole nie istnieje
 (wymagaja one dokladnego okreslenia typu danych).


 Niektore instrukcje (LDS, LES,  LSS,  LFS,  LGS,  LGDT,  LIDT,  SGDT,  SIDT)
 pozwalaja na 6-bajtowe argumenty i poprzez to na uzywanie  typu  FWORD  przy
 operacji nakladania. Dotyczy to zestawu instrukcji 386. Inne zestawy jak np.
 FPU, MMX itp. korzystaja z odpowiednich dla  nich  typow DWORD, QWORD, TBYTE
 oraz OWORD/DQWORD.



 15.8. Zmiana domyslnego segmentu
 --------------------------------

 Przy odwolaniach do danych (pamieci) mozliwe jest  korzystanie  z  dowolnego
 rejestru segmentowego.  XAssembler  udostepnia  przedrostki  pozwalajace  na
 zmiane domyslnego segmentu. Ich stosowanie mozliwe jest tylko w  odwolaniach
 z nawiasem kwadratowym.

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

 Dostepne sa  nastepujace  przedrostki : "cs:", "ds:", "es:", "ss:", "fs:"  i
 "gs:" (co odpowiada wszystkim dostepnym rejestrom  segmentowym).  Kompilator
 wymaga aby uzyty przedrostek byl wymieniony jako pierwszy w nawiasie.



 15.9. Adresowanie skokow CALL, JMP i Jcc
 ----------------------------------------

 XAssembler udostepnia wiele metod okreslania adresu docelowego w skokach.


 Adresowanie przez nazwe :

   call procedura
   jmp  etykieta
   jz   etykieta

 Kompilator dopuszcza skoki JMP/Jcc do procedur i CALL do etykiet.  W  czasie
 kompilacji przy  napotkaniu  takich  odwolan  wyswietlane  jest  odpowiednie
 ostrzezenie.


 Adresowanie przez funkcje :

   call ofs procedura
   jmp  ofs etykieta
   jz   ofs etykieta

 Nalezy zauwazyc, ze w przeciwienstwie do odwolan  do  danych  znaczenie  obu
 powyzszych zapisow jest  takie samo.  Adresowanie  przez  funkcje  umozliwia
 dodatkowo stosowanie wyrazen numerycznych do okreslenia adresu.

   call ofs procedura + 2
   jmp  ofs etykieta - 0Fh
   jz   ofs etykieta - 4


 Adresowanie przez rejestr i pamiec :

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

 Skoki warunkowe nie moga byc adresowane w powyzszy sposob.


 Adresowanie wzgledne :

   call @ - 3
   jmp  @ + 2
   jz   @

 W adresowaniu wzglednym znak @ oznacza adres kolejnej instrukcji  po  skoku.
 Pozwala  to  na  bezposrednie  okreslenie  odleglosci  skoku  wzgledem   tej
 instrukcji. Dodatkowo XAssembler udostepnia stala predefiniowana _ip (_eip),
 wskazujaca adres aktualnej instrukcji.

   jz @
   jz _eip

 Obie instrukcje w powyzszym przykladzie wykonuja skok pod ten sam adres.


 Adresowanie z wyborem rodzaju skoku (SHORT, NEAR, FAR) :

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

   * - Segment i offset oddzielone sa znakiem ":".


 Adresowanie z wyborem typu przesuniecia (tylko skoki NEAR i FAR) :

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

   * - Typ przesuniecia podawany jest przed aktualna wartoscia adresu.

 Dalekie skoki sa rozpoznawane tylko po okreslonym rodzaju skoku. W przypadku
 jego braku zawsze przyjmowany jest rodzaj NEAR.



 ----------------------------------------------------------------------------
 16. Dyrektywy lokalne (przelaczniki)
 ----------------------------------------------------------------------------

 XAssembler udostepnia szereg  dyrektyw  lokalnych  pozwalajacych  dokladniej
 kontrolowac sposob generacji kodu. Dyrektywy  te  zachowuja  sie  zgodnie  z
 zasada "dzialaj od miejsca wystapienia" i w wiekszosci przypadkow  posiadaja
 odpowiedniki dajace odwrotny efekt. Stad wynika ich zdolnosc do dzialania na
 wybranych fragmentach kodu.

 Zestawienie dyrektyw lokalnych.

 ----------------------------------------------------------------------------
  Dyrektywa       | Dzialanie
 ----------------------------------------------------------------------------
  {16+}/{16-}     | wlacza/wylacza generowanie kodu 16-bitowego
  {32+}/{32-}     | wlacza/wylacza generowanie kodu 32-bitowego
  {aN}/{a-}       | wlacza/wylacza wyrownywanie do N bajtow
  {c+}/{c-}       | wlacza/wylacza automatycznie dopelnianie adresow *
  {g+}/{g-}       | wlacza/wylacza wyrownywanie procedur i etykiet globalnych
  {j-}            | wylacza skok startowy
  {l+}/{l-}       | wlacza/wylacza wyrownywanie danych i etykiet lokalnych
  {o+}/{o-}       | wlacza/wylacza zoptymalizowane formy instrukcji *
  {p+}/{p-}       | wlacza/wylacza wyrownywanie do granicy paragrafu (16 bajtow)
  {r+}/{r-}       | wlacza/wylacza automatyczne wstawianie instrukcji RET *
  {s-}            | wylacza inicjacje segmentow
  {t+}/{t-}       | wlacza/wylacza wyrownywanie adaptywne *
  {z+}/{z-}       | wlacza/wylacza usuwanie zerowego przesuniecia *
 ----------------------------------------------------------------------------
  {386}           | ogranicza zestaw instrukcji tylko do 386
  {fpu+}/{fpu-}   | wlacza/wylacza instrukcje 387+ FPU
  {486+}/{486-}   | wlacza/wylacza instrukcje 486
  {pent+}/{pent-} | wlacza/wylacza instrukcje Pentium
  {x86}           | wlacza wszystkie instrukcje dostepne w tej wersji *
 ----------------------------------------------------------------------------

 * - Przelaczniki domyslnie wlaczane.


 Przelaczniki  {16-} i {32+}, podobnie jak  {16+} i {32-},  sa  jednoznaczne.
 Zostaly wprowadzone jedynie dla ulatwienia.

 Przelaczniki {a-} oraz {g-} przywracaja wyrownywanie do  wartosci  globalnej
 ustawionej dyrektywa ALIGN (0 jest nie byla ona uzyta).

 Przelacznik {c+}/{c-} pozwala kompilatorowi na dopelnianie  niektorych  form
 adresow nie obslugiwanych bezposrednio przez architekture x86.

 Przalacznik {j-} blokuje wstawienie rozkazu skoku  "JMP BEGIN"  na  poczatku
 kodu w trybach Bin, Com i Flat.

 Przelacznik {s-} blokuje wstawianie instrukcji inicjujacych segmenty DS i ES
 w miejsce dyrektywy BEGIN w trybach Small i Near.

 Przelacznik {r+}/{r-} odpowiada  za  wstawianie  instrukcji  RET  w  miejsce
 dyrektywy END w procedurach, nie ma on jednak zadnego wplywu  na  instrukcje
 wstawiane dyrektywa EXIT.

 Przelacznik {z+}/{z-} decyduje czy zerowe przesuniecia  beda  ignorowane. Ma
 on wplyw  tylko na formy  adresu "[rej + przesuniecie]", z wylaczeniem  form
 "[bp+0]/[ebp+0]".



 ----------------------------------------------------------------------------
 17. Wlaczanie plikow
 ----------------------------------------------------------------------------

 Kompilator pozwala na  wlaczanie  dodatkowych  plikow  zrodlowych  przez  co
 mozliwe jest podzielenie "dlugiego" programu na mniejsze czesci. Ulatwia  to
 takze  prace nad  programem  poprzez  podzial  na  moduly  wykonujace  rozne
 funkcje.

 Wlaczanie plikow dokonywane jest za pomoca dyrektywy INCLUDE.

   INCLUDE "nazwa pliku"

 Nazwe pliku wlaczanego nalezy ujac w apostrof. Tak  jak  w  przypadku danych
 XAssembler pozwala  na  uzycie  pojednczego  lub  podwojnego  apostrofu  pod
 warunkiem zastosowania tego samego rodzaju przed i po nazwie pliku.

 Podczas wczytywanie plikow XAssembler szuka ich w katalogu  pliku  glownego.
 Jezeli  plik  nie  moze  byc  odnaleziony,  kompilator  probuje   przeszukac
 podkatalog "INC" wlasnej sciezki instalacyjnej.

 Dyrektywa INCLUDE moze byc rozwniez stosowana w plikach  wlaczanych. Kolejne
 pliki mozna wlaczac do 20 poziomu. Daje to  wystarczajacy  zapas  nawet  dla
 bardzo rozbudowanych programow.

 Dyrektywa INCLUDE nie moze  byc  uzywana  w  bloku  wstepnym  programu  oraz
 wewnatrz procedur ani w module glownym. Innymi slowy kazda procedura i modul
 glowny musi zaczynac sie i konczyc w tym samym pliku.



 ----------------------------------------------------------------------------
 18. Wstawianie kodu
 ----------------------------------------------------------------------------

 XAssembler umozliwiwa  bezposrednie  wstawianie  kodu  binarnego  do  zrodla
 programu. Sluzy do tego dyrektywa INLINE, po ktorej nalezy umiescic  kolejne
 bajty kodu.

   INLINE bajt1, bajt2, bajt3, ... , bajtN

 Liczba wstawianych bajtow jest dowolna.   Metoda ta pozwala na korzystanie z
 instrukcji nie  obslugiwanych  przez  kompilator .  Dyrektywe  INLINE  mozna
 stosowac tylko wewnatrz procedur i modulu glownego.


 Drugim sposobem jest skorzystanie z dyrektywy INSERT. Dyrektywa ta umozliwia
 wstawienie wiekszego fragmentu kodu z zewnetrznego pliku.

   INSERT "nazwa pliku"

 Przy takim wywolaniu zawartosc wskazanego pliku bedzie bezposrednio uzyta do
 generacji pliku wynikowego. Dyrektywe INSERT mozna stosowac w obrebie calego
 bloku kodu. Oczywiscie nazwa pliku musi byc ujeta w apostrofy.



 18.1. Blad niezgodnosci segmentow
 ---------------------------------

 Problem ten dotyczy tylko dyrektywy INSERT  i  wstawiania  fragmentow  kodu,
 ktorych poprawna praca zalezy od polozenia w segmencie. Moze sie zdarzyc, ze
 segment wstawianego kodu nie bedzie  sie  pokrywal  z  segmentem  tworzonego
 programu -  w najlepszym wypadku spowoduje to bledne dzialanie programu.

 Wyjsciem z sytuacji jest korzystanie z  wyrownywania  do  granicy  paragrafu
 (przelacznik {p+}) i korzystanie  z  wywolan  dalekich  (tryby Small i Near)
 lub, o ile to mozliwe,  unikanie  takich  sytuacji  (tryby  tworzace  obrazy
 kodu).



 ----------------------------------------------------------------------------
 19. Programy 32-bitowe
 ----------------------------------------------------------------------------

 Poczawszy od  wersji  3.01  XAssembler  moze  tworzyc  rzeczywiste  programy
 32-bitowe oferujac tryb  kompilacji  Flat.  Oczywiscie  wciaz  mozliwe  jest
 tworzenie malych/srednich aplikacji DPMI w  trybach  16-bitowych  z  uzyciem
 przelacznikow {32+}/{32-} (taki przyklad zawiera katalog "Demo").

 Dodatkowo, tryb kompilacji Flat udostepnia kilka formatow pliku  wynikowego.
 Zastosowanie roznych formatow jest omowione ponizej.

 16-bitowa wersja XAssemblera ogranicza rozmiar kodu  generowanego  w  trybie
 Flat do 64k.



 19.1. Obrazy kodu
 -----------------

 Binarne obrazu kodu 32-bitowego moga byc tworzone przy uzyciu dyrektywy MODE
 z nazwa trubu "flat".
 
   MODE flat

 Tryb ten jest podobny do trybu Bin lecz  korzysta  domyslnie  z  32-bitowego
 ustawienia kodu. Stad wszystkie odwolania do danych/kodu  beda  korzystac  z
 32-bitowych wskaznikow. Wszystkie reguly trybu Bin maja zastosowanie takze w
 trybie Flat. Kompilator wstawi instrukcje JMP na poczatek obrazu o  ile  nie
 zostal uzyty przelacznik {j-}.



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

 XAssembler moze tworzyc 32-bitowe programy, ktore beda pracowac pod kontrola
 serwera DPMI. Proces ten jest podobny do  czystego  trybu  Flat  w  tym,  ze
 utworzony zostanie 32-bitowy obraz. Jednakze kompilator wygeneruje takze kod
 'loadera', ktory zainicjuje sesje DPMI i skoczy bezposrednio do  32-bitowego
 obrazu uzytkownika.

 Programy korzystajace z formatu DPMI musza rozpoczynac sie dyrektywa MODE w
 nastepujacej postaci.

   MODE flat, dpmi

 Kompilator utworzy plik EXE, ktory moze byc uruchamiany w srodowisku DOS-a z
 zainstalowanych serwerem DPMI.


 Format DPMI pozwala na uzywanie dyrektywy MEMORY. Jednakze  wazne  jest  aby
 zapamietac, ze stos i sterta zadeklarowana ta dyrektywa  musza  spelniac  te
 same kryteria co dla 16-bitowych programow DOS-owych  (64k  dla  stosu  oraz
 600000 bajtow dla sterty).

 Domyslny rozmiar stosu do 4096 bajtow (4k). Dla sterty jest to 0 (tak jak  w
 trybach 16-bitowych). Minimalny rozmiar stosu  to  32  bajty,  jednakze  nie
 powinien on byc stosowany z uwagi na rozne wymagania serwerow DPMI.

 Stos uzywany przez klienta DPMI jest tym samym, ktorego uzywa  loader  przed
 skokiem do kodu 32-bitowego. Oczywiscie aplikacja moze utworzyc  nowy  stos,
 ktorego rozmiar bedzie wiekszy niz 64k.


 Przy korzystaniu z formatu DPMI udostepnianego przez  XAssemblera  32-bitowy
 kod uzytkownika jest zawsze ladowany  do  pamieci  konwencjonalnej  (ponizej
 1-ego MB).  Stad maksymalny rozmiar programu (kod + dane + stos + sterta) to
 600k.


 Format DPMI zapewnia przekazanie w rejestrach kilku waznych wartosci do kodu
 uzytkownika. Sa to :

   EAX = adres bazowy kodu 32-bitowego
   EBX = selektor danych
   ECX = poczatkowa wartosc ESP, rowniez startowy adres sterty
   EDX = selektor bloku PSP

 Po uruchomieniu kodu uzytkownika model pamieci jest typu 'flat' co  oznacza,
 ze CS = DS = ES = SS. FS i GS sa wyzerowane. Format DPMI uzywa wartosci ORG
 rownej 8h, ktora nie moze byc zmieniona (dyrektywa ORG jest niedozwolona).
 Te 8 bajtow zawiera instrukcje inicjujace rejestry DS, ES, SS i ESP. Oznacza
 to takze, ze aktualny kod uzytkownika rozpoczyna sie od adresu CS:8h.

 Katalog "Demo" zawiera przykladowy program z dodatkowym komentarzem na temat
 korzystania z formatu DPMI.



 ----------------------------------------------------------------------------
 20. Przekazywanie wiadomosci w zrodle programu
 ----------------------------------------------------------------------------

 XAssembler udostepnia dwie dyrektywy pozwalajace na przekazywanie wiadomosci
 uzytkownikowi w trakcie kompilacji programu - MSG i PROGRESS.

   MSG "wiadomosc"

 Dyrektywa MSG po prostu wyswietla podana wiadomosc  zas  dyrektywa  PROGRESS
 pokazuje aktualny postep kompilacji w postacji "plik / linia"



 ----------------------------------------------------------------------------
 21. Wymuszenie zatrzymania kompilacji
 ----------------------------------------------------------------------------

 Czasem konieczne jest zatrzymanie kompilacji np. w  celu  unikniecia  bledu.
 Pomocna jest wtedy dyretkywa STOP. Po jej napotkaniu kompilator  natychmiast
 konczy prace wyswietlajac krotki komunikat "Stop!". Dodatkowo emitowany jest
 kod powrotu 255 (zob. rozdzial 30).



 ----------------------------------------------------------------------------
 24. Kompilacja programu
 ----------------------------------------------------------------------------

 Dla wiekszosci przypadkow skompilowanie programu sprowadza sie do  wywolania
 XAssemblera z nazwa pliku zrodlowego programu jako parametrem.  Cala  reszta
 nalezy juz do kompilatora.



 24.1. Uruchamianie kompilatora
 ------------------------------

 Uruchomienie XAssemblera jest bardzo  proste  -  wystarczy  w  linii  komend
 wpisac "XASM plik" i wcisnac  enter.  Oczywiscie  "plik"  to  plik  zrodlowy
 programu do kompilacji. Wskazane jest aby aktualnym  katalogiem  byl  ten  w
 ktorym znajduja sie pliki zrodlowe. Pomocne jest tutaj ustawienie  wlasciwej
 sciezki dostepu w pliku AUTOEXEC.BAT tak aby mozna bylo uruchomic kompilator
 z dowolnego katalogu.



 24.2. Opcje
 -----------

 XAssembler udostepnia szereg opcji pozwalajacych na  sterowanie  przebiegiem
 kompilacji jednak zadna z nich nie pozwala modyfikowac  zrodla  ani  wplywac
 na zawartosc pliku wynikowego (wyjatkiem jest tu opcja "-x").

 Przy wywolaniu opcje musza znajdowac sie pomiedzy nazwa kompilatora a
 nazwa pliku zrodlowego.

   xasm.exe -o1 -o2 ... -on plik_zrodlowy

 Nazwa pliku zrodlowego moze ale niu musi byc ujeta w apostrofy.  Pozwala  to
 na bezproblemowe korzystanie z dlugich nazw.

 Opcje kompilatora :

 "-c" - Wylacz buforowanie symboli (Disable symbol cache). Opcja  ta  wylacza
        wewnetrzne bufory kompilatora. Powinna byc stosowana tylko  w  bardzo
        rzadkich przypadkach kiedy struktura pliku zrodlowego nie pozwala  na
        wykorzystanie mozliwosci mechanizmu buforowania a wrecz utrudnia jego
        dzialanie.  Jednakze,  dla  wiekszosci  programow  warto   pozostawic
        buforowanie wlaczone.

 "-v" - Tylko weryfikuj zrodlo  (Verify  source  only).  Xassembler  dokonuje
        kompletnej kompilacji programu ale nie zapisuje pliku wynikowego.

 "-f" - Wymuszaj obsluge  LFN  (Force  LFN). Opcja ta  zmusza  kompilator  do
        obslugi dlugich nazw plikow  (uzywac  tylko  jesli  autodetekcja  nie
        zadziala).

 "-g" - Blokuj obsluge  LFN  (Disable  LFN). Opcja ta  zmusza  kompilator  do
        uzywania starych nazw plikow  w  formacie  8.3  (uzywac  tylko  jesli
        autodetekcja nie zadziala).

 "-q" - Blokuj  wiadomosci  (Disable  messages).   Kompilator  nie  wyswietla
        zadnych wiadomosci ani ostrzezen.

 "-r" - Generuj  raport  (Generate  report).  XAssembler  generuje  raport  z
        przebiegu kompilacji zawierajacy takze szczegolowa mape programu.

 "-m" - Tworz mape (Create map). Mapa  pokazuje  adresy  wszystkich  obiektow
        zdefiniowanych w programie po  tym  jak  zostanie  on  zaladowany  do
        pamieci w celu wykonania.

 "-o" - Okresl plik wynikowy (Specify output file).  Opcja  pozwala  okreslic
        inna  nazwe  pliku  wynikowego  niz  domyslna .  Nazwe  trzeba  podac
        bezposrednio po opcji.

 "-w" - Zapisz plik wynikowy  do  zdalnego  katalogu  (Save  output  file  to
        remote dir). Kompilator zapisze plik wynikowy do  katalogu, w  ktorym
        znajduje sie plik zrodlowy niezaleznie od aktualnego katalogu.

 "-e" - Uzyj zewnetrznego pliku "linii komend" (Use  extarnal  "command line"
        file). XAssembler umozliwia  ominiecie  ograniczenia  dlugosci  linii
        komend poprzez wykorzystanie do tego celu odrebnego pliku tekstowego.
        Nazwe pliku nalezy podac bezposrednio po opcji. Oczywiscie  zawartosc
        wskazanego pliku to nic innego jak zawartosc linii komend.
        
 "-x" - Redukuj rozmiar pliku EXE (Reduce EXE file size).  Opcja  ta  pozwala
        zmniejszyc rozmiar pliku wynikowego dla  16-bitowych  programow  typu
        EXE  (tryb Near).  Oszczednosc  moze  wyniesc  nawet  do  64k  jednak
        wymaga to okreslonego  sposobu  definiowania  danych  globalnych.  Po
        prostu dane niezainicjowane musza byc zdefiniowane  jako  ostatnie  w
        bloku danych. Pozwala to na skorzystanie z pewnych  wlasnosci formatu
        EXE i zaoszczedzenie miejsca na dysku. Metoda  ta  stosowana  byla  z
        powodzeniem juz we wczesniejszych wersjach.

        Efektem ubocznym jest  brak  gwarancji  wartosci  poczatkowej  0  dla
        zmiennych nie zainicjowanych (zob. punkt 5.3).

 "-p" - Pokazuj pelne sciezki w komunikatach (Show full paths  in  messages).
        XAssembler wyswietla pelne sciezki (dysk, katalog oraz  nazwa  pliku)
        we wszystkich komunikatach.

 "-s" - Pokazuj status programu (Show program status). Opcja  ta  pozwala  na
        uzyskania  dodatkowych  informacji  o  przebiegu  kompilacji   takich
        jak : nazwa pliku zrodlowego, tryb,  stos i sterta,  rozmiar  pamieci
        jaka  wykorzystuje  kompilator  a  takze  czas  trwania  kompilacji z
        dokladnoscia do 1ms.

 "-t" - Pokazuj dodatkowe statystyki (Show extra statistics) dla biezacej
        sesji kompilatora.

 "-?" - Pokaz pomoc.

 "-i" - Pokaz dodatkowe informacje.



 ----------------------------------------------------------------------------
 26. Stale predefiniowane
 ----------------------------------------------------------------------------

 XAssembler udostepnia kilka predefiniowanych stalych. Sa  one  traktowane  w
 taki sam sposob jak zwykle stale  definiowane  dyrektywa  Set  za  wyjatkiem
 wyrazen warunkowych.

  -----------------------------------------------
   Stala  | Przedstawiana wartosc
  -----------------------------------------------
   _mode  | tryb kompilacji *
   _ver   | wersja kompilatora **
  -----------------------------------------------
   _bits  | rodzaj generowanego kodu ***
   _ip    | ip aktualnej instrukcji
   _eip   | eip aktualnej instrukcji
   _dtp   | aktualny wskaznik danych w definicji
  -----------------------------------------------
   _cseg  | segment kodu
   _dseg  | segment danych
   _sseg  | segment stosu
   _hseg  | segment sterty
  -----------------------------------------------
   _ssize | rozmiar stosu
   _hsize | rozmair sterty
   _dsize | rozmiar danych
   _csize | rozmiar kodu
   _msize | rozmiar modulu
  -----------------------------------------------

  *   - Numery trybow sa nastepujace :
          1 - Bin
          2 - Com
          3 - Small
          4 - Near
          5 - Flat

  **  - Kodowanie wersji odbywa sie w nastepujacy sposob :

          bit 11   bit 0
          |            |
          AAAA BBBB CCCC

        gdzie numer wersji to A.BC (najstarsze cztery bity wyzerowane).
        Dla wersji 3.12 wartosc stalej _ver wynosi 312h.
      
  *** - Stala przyjmuje wartosci 16 i 32 odpowiednio dla kodu 16-bitowego i
        32-bitowego.


 Stale _cseg, _dseg, _sseg, _hseg, _size i _hsize moga byc stosowane  tylko w
 trybach Small i Near.

 Stale _dsize i _csize moga byc stosowane wylacznie w trybie Near.


 W zwiazku ze sposobem wyliczania wartosci  przez  kompilator  jedynie  stale
 _mode, _ver i _bits moga byc stosowane w wyrazeniach warunkowych.



 Dodatki



 ----------------------------------------------------------------------------
 29. Zestawienie opcji kompilatora
 ----------------------------------------------------------------------------

 Opcja       Opis
 --------------------------------------------------------
 -c          wylaczenie buforowania symboli
 -v          weryfikacja zrodla
 -f          wymuszenie obslugi dlugich nazw plikow
 -d          blokada obslugi dlugich nazw plikow
 -q          "cichy" tryb - brak komunikatow
 -r          generowanie raportu (log)
 -m          tworzenie mapy

 -o "plik"   okreslenie pliku wyjsciowego
 -w          zapis pliku wyjsciowego do zdalnego katalogu
 -e "plik"   uzycie zewnetrznego pliku parametrow
 -x          redukcja rozmiaru pliku wynikowego
 -p          wyswietlanie pelnych sciezek w komunikatach
 -s          wyswietlenie statusu programu
 -t          wyswietlenie dodatkowych statystyk

 -?          pomoc
 -i          dodatkowe informacje o kompilatorze
 --------------------------------------------------------



 ----------------------------------------------------------------------------
 30. Lista dyrektyw kompilatora
 ----------------------------------------------------------------------------

 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. Kody bledow
 ----------------------------------------------------------------------------

 Kod bledu jest wartoscia zwracana przez  kompilator  po  zakonczeniu  pracy.
 Mozna z niego korzystac w plikach wsadowych poprzez zmienna ERRORLEVEL.

 Kod        Opis                                   Komunikat w oryginale
 ----------------------------------------------------------------------------
  0         bez bledu - kompilacja pomyslna :)

  1         zle parametry kompilatora              bad compiler parameters
  2         brak wystarczajacej ilosci pamieci     not enough memory
  3         brak procesora 386 (lub nowszego)      no 386
  4         brak serwera DPMI                      no 32-bit DPMI server present
  5         niespojne parametry programu           inconsistent program parameters
  6         tryb kompilacji nie zaimplementowany   mode not implemented
  7         przekroczone ograniczenia trybu        mode restrictions exceeded
  8         zbyt wiele relokacji                   too many relocations

  9..10     - zarezerwowane -

  11        nie mozna wczytac biblioteki/obiektu   unable to read library/object
  12        bledny format biblioteki/obiektu       invalid library/object format

  13        - zarezerwowane -

  14        nie mozna zapisac pliku docelowego     unable to write target file
  15        nie mozna odczytac pliku zrodlowego    unable to read source file
  16        nieoczekiwany koniec pliku             unexpected end of file

  18..40    - zarezerwowane -

  51        zarezerwowana nazwa symbolu            reserved symbol name                
  52        symbol juz zdefiniowany                symbol already defined
  53        nieznany symbol                        unknown symbol reference
  54        nieprawidlowe uzycie symbolu           invalid symbol reference
  55        nieprawidlowe wyrazenie numeryczne     invalid numeric expression
  56        nieprawidlowe wyrazenie warunkowe      invalid conditional expression
  57        niezgodnosc typu                       type mismatch
  58        nieprawdlowa specyfikacja adresu       invalid address specification
  59        brak nazwy symbolu                     missing symbol name
  60        brak argumentu instrukcji              missing instruction argument
  61        nieprawidlowy argument instrukcji      invalid instruction argument
  62        wartosc poza zakresem                  value out of range
  63        wyrazenie numeryczne za dlugie         expression too long
  64        wywolania dalekie nie dozwolone        far call/jump not allowed
  65        cel skoku poza zakresem                jump target out of range

  66..70    - zarezerwowane -

  71        dyrektywa nie dozwolona                directive not allowed
  72        instrukcja nie dozwolona               instruction not allowed

  73..79    - zarezerwowane -

  80        blad skladni                           syntax error
  81        sekcja repeat nie zamknieta            repeat section not closed

  82..90    - zarezerwowane -

  91        typ nie obslugiwany w wyrazeniu        data type not supported
  92        multidefinicje nie zaimplementowane    multidefinitions not implemented
  93        wartosc stalej nie dostepna            constant value not available
  94        funkcja nie zaimplementowana           function not implemented
  95        tablice inic. nie zaimpelemtowane      initialized arrays not implemented
  96        liczby rzeczyw. nie zaimplementowane   float numbers not implemented
  97        dyrektywa nie zaimplementowana         directive not implemented
  98        instrukcja nie zaimplementowana        instruction not implemented
  99        wyrazenie num. nie zaimplementowane    numeric expressions not implemented

 100..252   - zarezerwowane -

 253        awaryjne zamkniecie kompilatora        compiler emergency shutdown

 254        - zarezerwowane -

 255        zamkniecie dyrektywa STOP
 ----------------------------------------------------------------------------

 Kody bledow 6 i 91..99 zmienia sie w przyszlych wersjach.



 ----------------------------------------------------------------------------
 32. Xassembler w sieci
 ----------------------------------------------------------------------------

 Strona domowa : http://xasm.webpark.pl/xasm

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

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