+----------------------+
                            |Assembler pro blbé č.1|
                            +----------------------+

      Nedávno  jsem  narazil  na  perfektní  text  o assembleru a grafice.
      Prokousal  jsem  se  tím  a naučil se to. Myslím, že to bude zajímat
      více  lidí,  takže  z  toho  vyrobím seriál na pokračování. Rád bych
      upozornil,  že  jsem  taky  začátečník.  Prosím  tedy  staré zkušené
      Assemblerovské  psy  aby  neváhali  a  radili  a  kritizovali. Často
      použiju dvě instrukce místo jedné, a o spoustě fint nemám určitě ani
      tušení.  Očekávám  taky,  že  mi  vážení  čtenáři budou psát maily s
      požadavky  co  nepochopili  tak  docela  úplně.  Rád  svou  rychlost
      přizpůsobím  vašemu chápání. Takže mě klidně brzděte. Popohánění asi
      budete  mít  marné,  protože  jsem  docela  blbej  a  nemůžu  vám to
      vysvětlovat  rychleji,  než se to stačím učit. Takže do toho skočíme
      rovnýma nohama:

                                   +--------+
                                   |Registry|
                                   +--------+

      Registry jsou něco jako proměnné ve vyšších programovacích jazycích.
      Průser  je  ovšem  v  tom,  že  je  jich  dost  málo.  Registry jsou
      většinou  16  bitové.  Některé  se  dají rozdělit na dva 8mi bitové.
      Třeba  16ti  bitový  registr  AX můžete používat jako dva 8mi bitové
      jménem  AL  a  AH.  Když  vrazím do registru AX třeba hodnotu 0ABCDh
      (zvykněte si psát před hexa číslici nulu, pokud to je písmeno), bude
      AL  obsahovat  0CDh  a AH bude obsahovat 0ABh, jasan? Jestli ne, tak
      pište,  pište.  Takto  můžete  rozpůlit  každý  registr, který končí
      iksem. Dostenete potom dva kousky, jeden H a jeden L Podíváme se, co
      tu máme:

      AX - Takový jeden nejpoužívanější registr.
      BX - Další podobný
      CX - Umí to co ti nad ním, ale navíc se používá jako čítač ve
           smyčce.
      DX - Poslední z této čtveřice

      DS, ES, CS, SS - Segmentové registry. Viz dále

      SI, DI - Indexové registry, používají se pro práci s řetězci a poli.

      A  pak  je  tu  ještě  pár  dalších,  ty  si necháme až napak (až je
      pochopím)

                              +-----------------+
                              |Segment & Offset:|
                              +-----------------+

      Když  kdysi  dávno  (když  na  zemi  vládli dinosauři) páni navrháři
      vynalézali  procesor  Intel 8086, rozhodli se, že ho vynaleznou tak,
      aby měl 16ti bitové registry a aby šířka jeho adresové sběrnice byla
      20  bitů.  Chvíli jen tak seděli a byli ze své geniality úplně paf a
      pak se jeden z nich poškrábal na hlavě a povídá:

      "Tož chlapi, šak to je ňáké divné né?"
      "Esli  máme  20bitovů  adresu,  tož  to možeme měť přístup k jednému
      megabajtovi, fíííha tož to ja."
      "Ale  chlapi esli máme v jedném registru eném 16 bitů, tak sa k temu
      nemóžeme nijak dostať. Šak 16bitů to stačí eném na 64 kilobajtů."

      Tak  zase  chvilku  seděli,  nervózně  krčili počítačové sjetiny, až
      jeden na to kápnul:

      "Já to mám, na přístup k paměti použijeme registry dva!"

      Jak řekli, tak udělali, ale udělali složitě.
      Představte  si  paměť  jako  řadu  paměťových buněk. Tyto buňky jsou
      očíslovány  od  0  po  0FFFFFh,  je to celkem megabajt. Pokud chcete
      zjistit  hodnotu,  která  je  uložena na některé adrese, můžete říct
      třeba,  že  chcete hodnotu z adresy 1ABCh. To můžete říct vy, ale ne
      procesor.  Ten  má  celou  paměť  rozdělenou  na  kusy  o  velikosti
      šestnácti  bajtů. Když přistupujete na nějakou adresu udáte nejdříve
      číslo  oné  šestnáctice.  To  je tzv Segment, jako druhý údaj dodáte
      offset, což je posunutí od začátku vámi zadaného segmentu. Síla co?
      Takže  třeba  adresa 0000:0000 (Segment a Offset se od sebe oddělují
      dvojtečkou)  je  vlastně  adresa 0. Adresa 0000:0100h, je totéž jako
      "přímá  adresa" 0100h.  Ovšem  tuto  adresu  můžete zapsat také jako
      0001:00F0h  a  nebo  000A:0060h,  všechny  tyto  adresy  ukazují  na
      stejné místo, tedy na 0100h buňku paměti.

               Skutečnou adresu získáte takto: 16*Segment+Offset

      Naučte  se tyto adresy nepřepočítávat, naučte se myslet v segmentech
      a offsetech. Toto je ta nejtěžší část strojového programování.

                         +-----------------------------+
                         |Takže prvních pár instrukcí: |
                         +-----------------------------+

      MOV AX, 0FFFFh      Do registru AX uloží hodnotu 0FFFFh

      MOV AX, BX          Hodnotu, která je v registru BX, zkopíruje do AX
                          (AX = BX)

      MOV AX, [0000:1234] Hodnota, která  je uložena v paměti na adrese
                          0000:1234 se zkopíruje do AX (AX=Mem[0000:1234])

      MOV AX, [1234]      Je to totéž jako výše, ale není zde zadán
                          segment. V takovém  případě se segmentová část
                          adresy vezme z registru DS (Data Segment)
                          (AX=Mem[DS:1234])

      MOV AX, [CS:1234]   Opět stejné, ale tentokrát jsem přímo uvedl, že
                          segmentovou část chci vzít z registru CS
                          (Code Segment)

      MOV AX, [DS:SI]     Jasné že? Segmentová část je v DS a offset
                          je v SI.

      Všimněte  si, že AX je 16bitový registr. Obsahem paměťového místa je
      ovšem  bajt,  tedy  8  bitů,  takže takovéto přirazení načte bajt ze
      zadané adresy ten uloží do AL a načte bajt z adresy+1 a uloží jej do
      AH.

      Teď  si  předvedeme  hrátky  s  registrem CX. Tento registr se kromě
      jiného  používá jako čítač. Existuje instrukce LOOP, která zmenší CX
      o  jedničku  a  pokud  není  nulový,  skočí na zadané návěští, takže
      třeba:

         mov cx, 100          ;Smycku budu opakovat stokrat.
      SMYCKA:                 ;Navesti, sem se budu vrhat
         ble, ble, ble        ;Tady neco pocitam, atd...
         ble
         ble
         ble, ble
         a furt pryc
         loop SMYCKA          ;A znova dokola, stokrat.

      A  co  třeba  indexové  registry:  Budu chtít znulovat oblast paměti
      velkou 100 bajtů od adresy 100:200h

         mov   ax,   100h       ;Do DS nemuzu priradit hodnotu primo
         mov   ds,   ax         ;musim pres druhy registr
         mov   di,   200h       ;ted mi DS:DI ukazuje na prvni bajt
                                ;nulovane oblasti
         mov   ax,   0          ;Nuluju, tak je to nula
         mov   cx,   100        ;Nuluju 100 bajtu
      Nuluj:
         mov   [ds:di],   ax    ;Vrazim nulu na adresu DS:DI
         inc   di               ;A posunu se na dalsi adresu
         loop  Nuluj            ;To cele stokrat

      Jasan?   Indexový  registr  je  vlastně  ukazatel  v  rámci  jednoho
      segmentu.  Díky  tomu,  že je to registr a jeho hodnota se tedy může
      měnit, můžu stejným programem adresovat různá místa. Časem poznáte i
      výkonější instrukce, které dělají hromadu věcí na jeden příkaz.

      Mým  dnešním záměrem je ukázat, že je stroják rychlejší než cokoliv,
      takže zkusme vyrobit strašně rychlé přesouvání paměti.

      +-----------------------------------------------------------------+
      |.MODEL SMALL                                                     |
      |.CODE                                                            |
      |.386                                                             |
      |  Obrazovka   dw   0B800h      ;adresa bloku v pameti            |
      |  Kusanec     dw   1000        ;Kolik 4bajtu budu presouvat      |
      |  Kus2        dw   2000        ;Kolikrat budu sunout             |
      |                                                                 |
      |START:                         ;Tady zacina program              |
      |  mov   cx,   [cs:Kus2]                                          |
      |  mov   ds,   [cs:Obrazovka]                                     |
      |  mov   es,   [cs:Obrazovka]                                     |
      |Smycka:                                                          |
      |  push  cx                                                       |
      |  mov   si,   2                ;DS:SI odkud presouvam            |
      |  mov   di,   0                ;ES:DI kam presouvam              |
      |  mov   cx,   [cs:Kusanec]     ;Kolik presouvam                  |
      |  rep   movsd                  ;CXkrat presunu [ES:DI] = [DS:SI] |
      |  pop   cx                                                       |
      |  loop  Smycka                                                   |
      |  mov   ax,   4c00h            ;Konec programu, navrat do DOSu   |
      |  int   21h                                                      |
      |END START                                                        |
      +-----------------------------------------------------------------+

      Část  v  rámečku vykopírujte do samostatného fajlu. Dejte mu příponu
      ASM a předhoďte jej assemblerovi.

      TASM.EXE nazev
      TLINK.EXE nazev.OBJ

      A  je  z  toho  EXE.  Udělejte  si baťák, který tento program spustí
      alespoň   desetkrát.  Teď  si  napište  ve  vašem  oblíbeném  vyšším
      programovacím  jazyku  program,  který  přesune 2000krát 4000bajtů z
      adresy  0B800:0002 na adresu 0B800:0000. To je to, co dělá prográmek
      nahoře. Vyrobte baťák na 100 opakování a měřte.

      Pokud  se  se  mnou  budete  chtít  spojit  máte dvě možnosti FIDO a
      internet.
      Moje fidonetí adresa je 2:421/59.
      A internetí je:         SysOp@pizi.fido.cz

                             Čaute příště  PIŽI


            výheň