Tm tiedosto on koottu CyberDyne Magazine:ssa ilmestyneen
'Assy Ohjelmointikurssi' -sarjan ensimmisest osasta. Sen
levittminen elektronisessa muodossa muuttamattomana on
sallittua ja jokainen saa omaa kyttn varten printata
sen kokonaisuudessaan tai osia siit. Sarjan toimitti
alunperin Antti Niskanen. Tmn tiedoston on koonnut
Antti Niskanen.

=====Kurssin ensimminen osa===============================================
=====Ilmestyi numerossa 08/94==============================================

                       O P I   O H J E L M O I M A A N 

            ˿ ˿ ˿    ˿             ˿
            δ ˿ ˿ ͹             δ
                        

  Ŀ
   Assylla  eli symbolisella konekielell ohjelmointi ei ole lainkaan niin 
   vaikeata kuin monet luulevat.  Sit varten ei vlttmtt tarvitse edes 
   kntj,   sill  kaikilla,  joilla on MS-DOS,   pitisi  kyll  olla 
   semmonen  ohjelma  kuin DEBUG.  Tll on helppo vst  pieni,   mutta 
   hydyllisi  ohjelmia,  monenlaisiin tarkoituksiin.  Sitten kun  haluaa 
   ruveta  harrastamaan  todellista assembleri ohjelmointia,   voi  imasta 
   jostain  (vaikkapa CyberDynest)  todellisen kntjn ja ostaa (taikka 
   imasta!)   jostain  kunnon assy oppikirjan.  Mutta  tm  lyhyt  kurssi 
   keskittyy vain ja ainoastaan assyn alkeisiin DEBUGilla. Siit on sitten 
   helppo  jatkaa oma-aloitteisesti eteenpin.  Itsekin aloin opiskelemaan 
   konekielen alkeita juuri tll tavalla.                                 
  

  Ŀ
   Ensin tutustumme hieman siihen, miten tietokoneen prosessori toimii. Se 
   pit sislln rekistereit, joiden nimet ovat AX, BX, CX, DX, SI, DI, 
   CS,  DS, ES, SS, SP, BP, IP ja FLAGS.  Opimme kyttmn niit kaikkia, 
   muttei   kaikki  kerralla.   Ensin  tutustumme  AX,   BX,   CX  ja   DX 
   rekistereihin.   Rekisteri  AX kutsutaan yleens nimell  akku.   Sit 
   voidaan  ksitell yhten yksikkn tai kahtena yksikkn.  Itse akkuun 
   AX mahtuu yhden sanan eli kahden tavun verran tietoa,  siis yhteens 16 
   bitti  (yhdess  tavussa  on  8  bitti).   Tavu  ilmoitetaan  yleens 
   heksadesimaalijrjestelmn lukuna, jossa kymmenen luvun 0-9  sijasta on 
   kuusitoista lukua:  0  1 2 3 4 5 6 7 8 9 A B C D E  ja F.  Yksi tavu on 
   heksadesimaalijrjestelmss kahden numeron pituinen,  ja se saa arvoja 
   aina 00:sta FF:n (desimaalijrjestelmss 0-255) asti. AX voi tllin 
   saada  arvoja 0000:sta FFFF:n asti (0-65535 desimaalijrjestelmss). 
   Akkua  voidaan mys ksitell kahtena palasena:  AL ja AH.  AH on  AX:n 
   ensimminen  eli  ylempi tavu,  AL on AX:n alempi tavu.  Jos  AH=4C  ja 
   AL=01, on AX=4C01. Muut X-loppuiset rekisterit toimivat samalla tavalla 
   kuin AX,  nekin jakautuvat kahteen osaan. Esimerkiksi CX jakautuu osiin 
   CH ja CL, ja DX jakautuu osiin DH ja DL.                                
  

  Ŀ
   Mutta mik ihme siis on rekisteri?  Jos olet koskaan ohjelmoinut jotain 
   kehittyneemp  kielt kuten BASIC,  Pascal tai C,  on muuttujan ksite 
   varmasti tuttu. Rekisteri on iknkuin muuttuja.  Jokaiseen rekisteriin 
   voidaan sijoittaa jokin arvo.  Tm arvo voi olla vlill 00-FF  mikli 
   kyse on AH,  AL,  BH,  BL...  rekistereist.  AX,  BX...  rekistereihin 
   voidaan  sijoittaa  mit  hyvns  arvoja  vlill  0000-FFFF.    Arvon 
   sijoittaminen  rekisteriin  tapahtuu  kskyll MOV,   joka  on  lyhenne 
   englanninkielisest sanasta MOVE. Kskyn rakenne on seuraavanlainen:    
                                                                           
               MOV <kohde>,<lhde>                                         
                                                                           
   <kohde> on rekisterin nimi ja <lhde> on arvo,  joka sinne sijoitetaan. 
   MOV   komennolla   voidaan   siirt  muistakin   kohteista   muihinkin 
   lhteisiin, mutta katsomme niit myhemmin. Esimerkkej:                
                                                                           
   MOV AX,1234         ;sijoittaa AX:n arvon 1234 (heksadesimaalia).     
   MOV BX,0000         ;nollaa BX-rekisterin.                              
   MOV DL,12           ;sijoittaa DX:n alempaan puolikkaaseen DL:n 12.   
   MOV AH,4C           ;sijoittaa AX:n ylempn puolikkaaseen AH:hon 4C.   
  

  Ŀ
   Joo, nyt osataan sijoittaa arvoja rekisteriin, mutta ents sitten? Mit 
   hyty siit on?                                                        
                                                                           
   Assylla  ohjelmoitaessa kytetn paljon ksky INT,  joka  on  lyhenne 
   englanninkielen  sanasta INTERRUPT,  suomeksi keskeytys.  Se keskeytt 
   ohjelman  suorittamisen  siksi aikaa kun kone tekee jotain muuta.   Se, 
   mit  kone tekee,  on ohjelmoitu valmiiksi joko koneeseen itseens  tai 
   DOS:iin.  Kun tehtv on suoritettu,  jatketaan ohjelman suorittamista. 
   Keskeytyksill  on  omat numeronsa,  ja jokainen  keskeytys  voi  tehd 
   useita eri tehtvi.  Yksi esimerkki siit, mit keskeytys voi tehd on 
   lukea   nppimistst   yhden  merkin.   Siihen   voitaisiin   kytt 
   keskeytyst numero 16  (heksadesimaalia!).  Se on BIOS-keskeytys eli se 
   on  koneeseen itseens tai muuhun ohjelmistoon kuin DOS:iin ohjelmoitu. 
   Keskeytys  16:ssa  on  kuitenkin monta eri toimintoa.  Merkin  luku  on 
   toiminto numero 00.  Toiminnon,  eli funktion numero sijoitetaan  ennen 
   keskeytyksen  kutsumista rekisteriin AH.  Jos siis  haluamme  aktivoida 
   keskeytyksen 16, funktion 00, kytmme komentoja                        
                                                                           
   MOV AH,00           ;Sijoittaa 00 AH-rekisteriin                        
   INT 16              ;Kynnist keskeytyksen 16.                        
  

  Ŀ
   Kun keskeytys on suoritettu loppuun,  kirjoitetaan mahdollinen  palaute 
   tiettyihin  rekistereihin.   Esimerkissmme keskeytys 16,   funktio  00 
   palauttaa   painetun   nppimen  ASCII-koodin,   ja   se   sijoitetaan 
   rekisteriin  AL.   Jos  esimerkiksi  painetaan  nppint  A  (iso  A), 
   rekisteriin  AL  tallentuu arvo 41h (h tarkoittaa  heksadesimaalia,   d 
   tarkoittaa  tavallista  kymmenjrjestelm eli desimaalia).  Arvon  voi 
   siirt  MOV kskyll AL:st muihin rekistereihin tai koneen  muistiin, 
   tai   kytten   muita  keskeytyksi  sen  saa  tulostettua   nytlle, 
   levykkeelle tai muihin laitteisiin.                                     
                                                                           
   Toinen  trke keskeytys on 21h (niin,  heksadesimaalia).  Se  on  DOS- 
   keskeytys,  jolla voidaan mys lukea merkkej nppimistst,  tulostaa 
   merkkej,   kirjoittaa  ja lukea levylle ja muuta kivaa.  Tss  osassa 
   assykurssia opimme keskeytyksen 21h funktion 4Ch.  Se lopettaa ohjelman 
   suorituksen  ja  palauttaa  kyttjn  DOSiin.   Se  aktivoidaan  kuten 
   edellinenkin  oppimamme  funktio,  4Ch sijoitetaan  rekisteriin  AH  ja 
   kynnistetn keskeytys 21h seuraavasti:                                
                                                                           
   MOV AH,4C                                                               
   INT 21                                                                  
  
 
  Assyohjelmointikurssi,osa1Ŀ
   Huomaa,   ettei  koodiin kirjoiteta h:ta pern,  sill  DEBUG  olettaa 
   numeroiden  olevan heksadesimaalia.  (Jaa miten DEBUGia kytetn?   Se 
   selvi kohta).                                                         
                                                                           
   Funktiossa 4Ch on ylimrinen ominaisuus. Se palauttaa rekisteriss AL 
   olevan   arvon  DOSille  ERRORLEVELin,   jota  voidaan  testata   BAT- 
   tiedostosta  ksin.  Tss vaiheessa voimme tehd huomion,  ett  juuri 
   tll  tavalla voimme hydynt keskeytys 16  funktio 00:n  palauttamaa 
   ASCII-arvoa, voimme ilmoittaa sen BAT-tiedostolle ERRORLEVELin. ASCII- 
   arvohan  palautettiin  valmiiksi AL:n,  joten meidn  tarvitsee  vain 
   kirjoittaa AH:hon 4C ja kynnist keskeytys 21. Nin:                  
                                                                           
   MOV AH,00                   ;Funktio 00                                 
   INT 16                      ;Keskeytys 16. Palauttaa AL:n koodin.     
   MOV AH,4C                   ;Funktio 4C                                 
   INT 21                      ;Keskeytys 21. Lopettaa ohjelman.           
                                                                           
   Huomaa  puolipiste (;)  ennen kommenttia.  Tavallisesti kommentteja  ei 
   kirjoiteta  DEBUGilla  ohjelmoitaessa,  sill ne katoavat  saman  tien, 
   mutta  assemblerilla ohjelmoitaessa ne  tallennetaan  lhdekooditiedos- 
   toon. Puolipiste ilmoittaa kntjlle, ett siit alkaa kommentti.     
  
 
  Ŀ
   Nyt kun ensimminen konekieliohjelmamme on suunniteltu,  voimme knt 
   sen.   Kynnistmme  DEBUGin komennolla DEBUG.   Saamme  yksinkertaisen 
   kehoitteen,   viivan  (-).   Kirjoitamme a100   <enter>.   Tm  kertoo 
   DEBUGille,   ett haluamme kirjoittaa koodia kntmist varten.  a  on 
   komento,    joka   tarkoittaa  Assemble  (knn)    ja   100    kertoo 
   muistiosoitteen,   johon haluamme koodimme sijoittaa.  Koska ohjelmasta 
   tulee .COM -tyyppinen,  tmn arvon tulee olla 100  (heksadesimaalia!). 
   Saamme  erilaisen kehoitteen,  joka ilmoittaa  muistiosoitteen,   johon 
   olemme koodia kirjoittamassa. Emme kiinnit huomiota thn osoitteeseen 
   nyt, vaan alamme kirjoittaa. Kirjoitamme:                               
                                                                           
   MOV AH,00                                                               
                                                                           
   ja painamme enteri.  Jos DEBUG hyvksyy sen,  saamme seuraavan  rivin, 
   ellei,  se ilmoittaa virheen.  Jos DEBUG hyvksyi sen,  voimme  jatkaa. 
   Kirjoitamme (ja tietysti painamme enteri jokaisen rivin jlkeen):      
                                                                           
   INT 16                                                                  
   MOV AH,4C                                                               
   INT 21                                                                  
  

  Assyohjelmointikurssi,osa1Ŀ
   Nyt  koodi  on kirjoitettu valmiiksi ja haluamme tallentaa sen  levylle 
   .COM  -tiedostoksi.   Painamme  enteri  kirjoittamatta  mitn  koodia 
   riville,  ja palaamme nin viiva kehoitteeseen. Kirjoitamme ngetkey.com 
   ja  painamme  enteri.  Ensimminen kirjain n kertoo  DEBUGille,   ett 
   haluamme antaa ohjelmalle nimen.  Sit seuraa itse nimi,  joka on  siis 
   getkey.com.  Sitten kirjoitamme rcx ja painamme enteri.  Nin kerromme 
   DEBUGille,   miten  pitk ohjelma tulee olemaan.  DEBUG j  odottamaan 
   numeroarvoa,   joka  kertoisi  pituuden.   Se on  helppo  laskea.   Kun 
   kirjoitimme  koodia,   rivin alussa oli  aina  muistiosoite.   Katsomme 
   viimeiselt   rivilt  muistiosoitteen  (silt  rivilt,   jonne   emme 
   kirjoittaneet mitn vaan painoimme vain enteri).  Se koostuu kahdesta 
   osasta,  jotka erotetaan toisistaan kaksoispisteell.  Meit kiinnostaa 
   se osa,  joka tulee kaksoispisteen jlkeen. Se on 0108 (ainakin pitisi 
   olla).   Vhennmme siit 100  (se sama arvo,  jota kytimme a-komennon 
   yhteydess!)   ja  saamme  siis 0008   eli  yksinkertaisemmin  vain  8. 
   Kirjoitamme siis 8 ja painamme enteri.  DEBUG tiet nyt,  miten pitk 
   ohjelma  on,   ja  mill nimell se tulee  tallentaa.   Sitten  annamme 
   komennon  w  joka tarkoittaa Write to disk (kirjoita  levylle).   DEBUG 
   kirjoittaa ohjelman levylle. Lopuksi komento q joka tarkoittaa Quit, ja 
   palaamme DOSiin. Katsomme DIR-komennolla hakemiston ja huomaamme siell 
   uuden ohjelman nimelt GETKEY.COM. Ensimminen konekielinen ohjelmamme! 
  
 
  Ŀ
   Mutta mit kummaa sill voi tehd? Kynnistetnps jokin editori, ihan 
   mik vain,  kunhan se tekee puhtaita tekstitiedostoja. DOS 5:n EDIT ky 
   thn hyvin.  Kirjoitamme seuraavan ohjelman (nimeksi vaikka TEST.BAT). 
   Ohjelma lytyy seuraavalta sivulta...                                   
  
 
           Ŀ
            ECHO OFF                                       
            ECHO Paina nppint A, jos haluat hakemiston. 
            ECHO Paina nppint B, jos haluat CHKDSK.     
            ECHO Muut nppimet lopettavat.                
            GETKEY                                         
            IF ERRORLEVEL 99 GOTO END                      
            IF ERRORLEVEL 98 GOTO B                        
            IF ERRORLEVEL 97 GOTO A                        
            IF ERRORLEVEL 67 GOTO END                      
            IF ERRORLEVEL 66 GOTO B                        
            IF ERRORLEVEL 65 GOTO A                        
            GOTO END                                       
            :A                                             
            DIR                                            
            GOTO END                                       
            :B                                             
            CHKDSK                                         
            GOTO END                                       
            :END                                           
           

  Assyohjelmointikurssi,osa1Ŀ
   Kun ajamme ohjelman,  voimme nppimill A tai B valita eri toimintoja. 
   Jos haluat,  voit jatkaa ohjelman kehittmist.  Se toimii siten,  ett 
   DEBUGilla  tekemmme  ohjelma lukee nppimen ja palauttaa  sen  ASCII- 
   koodin  ERRORLEVELin.   Voimme  katsoa,   mik  ERRORLEVELin  arvo  on 
   komennolla  IF ERRORLEVEL nn GOTO xxxxx.  Se katsoo,   onko  ERRORLEVEL 
   suurempi  kuin  tai yhtsuuri kuin annettu numero ja  hypp  annetulle 
   riville.  Rivi merkitn ohjelmaan kaksoispisteell,  jota seuraa rivin 
   tunnus,   esimerkissmme  :A,  :B tai :END.  Numerot  IF  ERRORLEVEL  - 
   komennoissa  tarkoittavat eri vaihtoehtojen ASCII-koodeja.   Lismll 
   rivej  voisimme  tehd  monipuolisen menu-systeemin,   jossa  jokainen 
   nppin  merkitsee eri komentoa.  Tllainen ei olisi mahdollista  ilman 
   GETKEY.COM -ohjelmaa,  jonka teimme juuri sken konekielell. DOS 6:ssa 
   tosin  on  jo komento,  joka tekee saman kuin juuri  tekemmme  GETKEY, 
   mutta  opimme  myhemmin tmn kurssin aikana tekemn  monipuolisempia 
   ohjelmia, jotka esimerkiksi ASCII-koodin sijasta kertovat ERRORLEVELin 
   oliko vastaus K vai E (tarkoittaen Kyll tai Ei),  ja palauttaa DOSille 
   ERRORLEVELiksi 1 tai 0.  Opimme mys lukemaan pivmrn ja kellonajan 
   konekielell,  tarkistamaan DOSin versionumeron, kntmn NUM-LOCKin, 
   SCROLL-LOCKin ja CAPS-LOCKin plle tai pois ohjelmasta ksin ja paljon 
   muuta  mielenkiintoista ja hydyllist.  Lis siis lehden  seuraavassa 
   numerossa.                                                              
  KirjoittanutUuki
