IAX0043   p r a k t i k u m
[ Laboritöö 3   infodokumendid . . . ]
Protsessorimudeli   K Ä S U S T I K

Protsessorimudeli nimeks on L-protsessor ehk L-CPU — mis tähendab mudeli autori järgi :   "LembituCPU".
Igas konkreetses Lab3 ülesandes läheb vaja ainult  väikest osa  kõikidest siinsetest käskudest.
Ühtegi käsku ega tema koodi ei pea "pähe õppima" — programmi koostamisel saab käske vaadata ja valida siit tabelist.   Kuid ettevalmistuse käigus vaata rahulikult (ehk “kaua”) seda tabelit ja saa aru, millist infot iga veerg siin esitab ja kuidas kahendkoodist tuleneb vastav HEX-kood.
Baidi jagunemist poolbaitideks   (sellekaudu ka HEX-numbriteks 0 . . . F )   on rõhutatud ka   [sinise | rohelise]   värviga.
Võrreldes tavaliste protsessoritega on see protsessorimudel lihtne :   tema käskude arv on väike ja mällupöördumise aadress on ainult 8-bitine, misjuhul adresseeritavat mälu saab olla ainult   256 baiti, mäluaadressidega   00h . . . FFh
L-CPU käsud on 1-baidised või 2-baidised.
Käsukood on ainult   5-j ä r g u l i n e   ja sisaldub alati käsu esimeses baidis.
Osad käsud teevad mingit tegevust järgmises baidis asuvate andmetega.  Selline täiendav lisabait kuulub samuti käsu juurde, mille tulemusel hõivab selline käsk mälus (1 baidi asemel) 2 järjestikust baiti, olles seega "2-baidine".

Käsku esitav bait koosneb kahest osast:
      k ä s u k o o d     
5
  kahendjärku


  ?     ?     ?     ?     ?
registri
spetsifikaator
 3
  kahendjärku 

?     ?     ?   
  . . . . [5bit + 3bit]   jaotusega   bait   esitub   
             [4bit + 4bit]   poolbaitidesse poolitatuna   
16nd   ehk   HEX-kujul :    

Osad käsud ei salvesta oma töötulemust mitte kuhugi registrisse (ehk nendel pole sihtregistrit olemas).
Sellised käsud ignoreerivad oma käsubaidi viimast 3 järku ehk registrispetsifikaatorit, misjuhul käsubaidi viimased 3 järku võivad olla täidetud suvalise koodikolmikuga   (ilma et see mõjutaks käsu toimimist).


R E G I S T R I
   s p e t s i f i k a a t o r

 järgukolmik käsubaidi lõpus : 

    käsk rakendub   registrile . . .    
? ? ? ? ? 0 0 0
[ mitte kuhugi ]  
? ? ? ? ? 0 0 1
Reg A
? ? ? ? ? 0 1 0
Reg B
? ? ? ? ? 0 1 1
Reg C
? ? ? ? ? 1 0 0
  mälu aadressiregister   ( MAR — Memory Address Register ) 
? ? ? ? ? 1 0 1
mälu andmeregister   ( MDR — Memory Data Register )
? ? ? ? ? 1 1 0
käsuloendur   ( PC — Program Counter )
? ? ? ? ? 1 1 1
Reg M


1-baidine
       k ä s u k o o d          
binary



  käsu  
p o o l b a i d i d
   kõrgem | madalam   



  k ä s u k o o d 
h e x
tuleneb poolbaitidest
 MNEMOkood 
lühike tähekobinatsioon, mis
 kirjapanduna võimaldab käsu üheselt äratunda 

 käsu pikkus 
  1 või 2 
baiti  ? 
käsu   kirjeldus
  0 0 0 0 0 ? ? ?  
  0 0 0 0 0 ? ? ?  
  0 0 
NOP
1
  tühikäsk    ( NO operation )
   ei tee andmetega mitte mingeid tegevusi;   progr. täitmisjärg (programmimälus) liigub järgmise käsu peale  
  0 0 0 0 1 ? ? ?  
  0 0 0 0 1 ? ? ?  
  0 ? 
LD[M]toREG
1
  laadib  RegM olevalt mäluaadressilt registrisse ???       ( load from memory address )
   mnemokoodi võimalikud erijuhud / näited :      LD[M]toA    LD[M]toB    LD[M]toC         ( "otsene  adresseerimine" )
  0 0 0 1 0 ? ? ?  
  0 0 0 1 0 ? ? ?  
  1 ? 
LDtoREG
2
  laadib  järgmisest mälubaidist registrisse ???         ( load from next byte )
   mnemokoodi võimalikud erijuhud / näited :      LDtoA databyte    LDtoB databyte    LDtoM databyte      ( "vahetu  adresseerimine" )
   0 0 1 0 0  ? ? ?  
  0 0 1 0 0 0 1 1  
    0 0 1 0 0 ? ? ?   
  0 0 1 0 0 0 1 1  
  2 3 
ST[M]fromREG
ST[M]fromC     
1
  salvestab  RegM olevale mäluaadressile registrist ???       ( store to memory address )
   mnemokoodi võimalikud erijuhud / näited :      ST[M]fromC         ( "otsene  adresseerimine" )
 ! praeguses protsessorimudelis :   see käsk ignoreerib registrispetsifikaatorit ??? ja töötab alati nii, nagu oleks spetsifikaatoriks 011 ehk RegC 
   0 0 1 0 1  ? ? ?  
  0 0 1 0 1 0 1 1  
   0 0 1 0 1 ? ? ?  
  0 0 1 0 1 0 1 1  
  2 B 
STfromREG
STfromC     
2
  salvestab  registrist ???   järgmisesse mälubaiti     ( store to next byte )
   mnemokoodi võimalikud erijuhud / näited :      STfromC databyte         ( "vahetu  adresseerimine" )
 ! praeguses protsessorimudelis :   see käsk ignoreerib registrispetsifikaatorit ??? ja töötab alati nii, nagu oleks spetsifikaatoriks 011 ehk RegC 
  0 0 1 1 0 ? ? ?  
  0 0 1 1 0 ? ? ?  
  3 ? 
CPfromAtoREG
1
  kopeerib  registrist A registrisse ???         ( copy from RegA to REG )
   mnemokoodi võimalikud erijuhud / näited :      CPfromAtoB    CPfromAtoC    CPfromAtoM     
  0 0 1 1 1 ? ? ?  
  0 0 1 1 1 ? ? ?  
  3 ? 
CPfromBtoREG
1
  kopeerib  registrist B registrisse ???         ( copy from RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      CPfromBtoA    CPfromBtoC    CPfromBtoM     
  0 1 0 0 0 ? ? ?  
  0 1 0 0 0 ? ? ?  
  4 ? 
CPfromCtoREG
1
  kopeerib  registrist C registrisse ???         ( copy from RegC to REG )
   mnemokoodi võimalikud erijuhud / näited :      CPfromCtoA    CPfromCtoB    CPfromCtoM     
  0 1 0 0 1 ? ? ?  
  0 1 0 0 1 ? ? ?  
  4 ? 
CPfromMtoREG
1
  kopeerib  registrist M registrisse ???         ( copy from RegM to REG )
   mnemokoodi võimalikud erijuhud / näited :      CPfromMtoA    CPfromMtoB    CPfromMtoC     
   0 1 0 1 1  ? ? ?  
  0 1 0 1 1 0 0 0  
   0 1 0 1 1 ? ? ?  
  0 1 0 1 1 0 0 0  
  5 8 
JMPZ addrbyte
2
 tingimusel kui (lipuregistris)  zero-lipp   Z=1, siis
 progr.täitmine siirdub  sellele aadressile, mis asub järgmises baidis       ( jump if ZERO to addr )
   mnemokoodi võimalikud erijuhud / näited :      JMPZ addrbyte   
 !   see käsk ignoreerib käsu koosseisus olevat registrispetsifikaatorit ???   kuna see käsk ei töötle andmeregistreid   RegA   RegB   RegC   RegM
   0 1 1 0 0  ? ? ?  
  0 1 1 0 0 0 0 0  
   0 1 1 0 0 ? ? ?  
  0 1 1 0 0 0 0 0  
  6 0 
JMPC addrbyte
2
 tingimusel kui (lipuregistris)  carry-lipp   C=1, siis
 progr.täitmine siirdub  sellele aadressile, mis asub järgmises baidis       ( jump if CARRY to addr )
   mnemokoodi võimalikud erijuhud / näited :      JMPC addrbyte   
 !   see käsk ignoreerib käsu koosseisus olevat registrispetsifikaatorit ???   kuna see käsk ei töötle andmeregistreid   RegA   RegB   RegC   RegM
   0 1 1 0 1  ? ? ?  
  0 1 1 0 1 0 0 0  
   0 1 1 0 1 ? ? ?  
  0 1 1 0 1 0 0 0  
  6 8 
JMPE addrbyte
2
 tingimusel kui (lipuregistris)  equal-lipp   E=1, siis
 progr.täitmine siirdub  sellele aadressile, mis asub järgmises baidis       ( jump if EQUAL to addr )
   mnemokoodi võimalikud erijuhud / näited :      JMPE addrbyte   
 !   see käsk ignoreerib käsu koosseisus olevat registrispetsifikaatorit ???   kuna see käsk ei töötle andmeregistreid   RegA   RegB   RegC   RegM
   0 1 1 1 0  ? ? ?  
  0 1 1 1 0 0 0 0  
   0 1 1 1 0 ? ? ?  
  0 1 1 1 0 0 0 0  
  7 0 
JMP addrbyte
2
 
 programmi täitmine siirdub  sellele aadressile, mis asub järgmises baidis       ( jump to addr )
   mnemokoodi võimalikud erijuhud / näited :      JMP addrbyte   
 !   see käsk ignoreerib käsu koosseisus olevat registrispetsifikaatorit ???   kuna see käsk ei töötle andmeregistreid   RegA   RegB   RegC   RegM
  1 0 0 0 0 ? ? ?  
  1 0 0 0 0 ? ? ?  
  8 ? 
AandBtoREG
1
 bitikaupa loogiline korrutamine AND  operandidega :   RegA    RegB
 tehte tulemus salvestatakse registrisse ???         ( RegA AND RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      AandBtoA    AandBtoB    AandBtoC    AandBtoM   
  1 0 0 0 1 ? ? ?  
  1 0 0 0 1 ? ? ?  
  8 ? 
AorBtoREG
1
 bitikaupa loogiline liitmine OR  operandidega :   RegA    RegB
 tehte tulemus salvestatakse registrisse ???         ( RegA OR RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      AorBtoA    AorBtoB    AorBtoC    AorBtoM   
  1 0 0 1 0 ? ? ?  
  1 0 0 1 0 ? ? ?  
  9 ? 
AnorBtoREG
1
 bitikaupa loogiline VÕI-EI tehe NOR  operandidega :   RegA    RegB
 tehte tulemus salvestatakse registrisse ???         ( RegA NOR RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      AnorBtoA    AnorBtoB    AnorBtoC    AnorBtoM   
  1 0 0 1 1 ? ? ?  
  1 0 0 1 1 ? ? ?  
  9 ? 
AxorBtoREG
1
 bitikaupa loogiline "summa mooduliga 2" tehe XOR  operandidega :   RegA    RegB
 tehte tulemus salvestatakse registrisse ???         ( RegA XOR RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      AxorBtoA    AxorBtoB    AxorBtoC    AxorBtoM   
  1 0 1 0 0 ? ? ?  
  1 0 1 0 0 ? ? ?  
  A ? 
A+BtoREG
1
 operandide RegA ja RegB aritmeetiline liitmine
 tehte tulemus salvestatakse registrisse ???         ( RegA + RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      A+BtoA    A+BtoB    A+BtoC    A+BtoM    ! see liitmiskäsk   ignoreerib / ei kasuta   lippuderegistri ülekandelippu   ( carryflag )
  1 0 1 0 1 ? ? ?  
  1 0 1 0 1 ? ? ?  
  A ? 
A-BtoREG
1
 operandide RegA ja RegB aritmeetiline lahutamine :   RegA - RegB
 tehte tulemus salvestatakse registrisse ???         ( RegA - RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :      A-BtoA    A-BtoB    A-BtoC    A-BtoM    ! see lahutamiskäsk   ignoreerib / ei kasuta   lippuderegistri ülekandelippu   ( carryflag )
  1 0 1 1 0 ? ? ?  
  1 0 1 1 0 ? ? ?  
  B ? 
AcmpB
1
 operandide RegA ja RegB võrdlemine   ( RegA compare RegB )
   mnemokoodi võimalikud erijuhud / näited :      AcmpB        võrdluskäsk   seab   lippuderegistri võrdsuslipu   ( equal-flag ) väärtust :   E=0    E=1
  1 0 1 1 1 ? ? ?  
  1 0 1 1 1 ? ? ?  
  B ? 
A+B+CARRYtoREG
1
 operandide RegA ja RegB ja ülekandelipu (carryflag)   aritmeetiline liitmine
 tehte tulemus salvestatakse registrisse ???         ( RegA + RegB + CarryFlag to REG )
   mnemokoodi võimalikud erijuhud / näited :      A+B+CARRYtoA    A+B+CARRYtoB    A+B+CARRYtoC    A+B+CARRYtoM   
 ! see liitmiskäsk   liidab   lippuderegistri ülekandelipu   ( carryflag ) juurde liidetavate madalaimasse järku
  1 1 0 0 0 ? ? ?  
  1 1 0 0 0 ? ? ?  
  C ? 
rorAtoREG
1
 RegA ringnihe paremale  1 järgu võrra
 nihutatud tulemus salvestatakse registrisse ???         ( ROR RegA to REG )
   mnemokoodi võimalikud erijuhud / näited :        rorAtoA    rorAtoB    rorAtoC    rorAtoM
  1 1 0 0 1 ? ? ?  
  1 1 0 0 1 ? ? ?  
  C ? 
rorBtoREG
1
 RegB ringnihe paremale  1 järgu võrra
 nihutatud tulemus salvestatakse registrisse ???         ( ROR RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :        rorBtoA    rorBtoB    rorBtoC    rorBtoM
  1 1 0 1 0 ? ? ?  
  1 1 0 1 0 ? ? ?  
  D ? 
rolAtoREG
1
 RegA ringnihe vasakule  1 järgu võrra
 nihutatud tulemus salvestatakse registrisse ???         ( ROL RegA to REG )
   mnemokoodi võimalikud erijuhud / näited :        rolAtoA    rolAtoB    rolAtoC    rolAtoM
  1 1 0 1 1 ? ? ?  
  1 1 0 1 1 ? ? ?  
  D ? 
rolBtoREG
1
 RegB ringnihe vasakule  1 järgu võrra
 nihutatud tulemus salvestatakse registrisse ???         ( ROL RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :        rolBtoA    rolBtoB    rolBtoC    rolBtoM
  1 1 1 0 0 ? ? ?  
  1 1 1 0 0 ? ? ?  
  E ? 
invAtoREG
1
 RegA inverteerimine  (kõik järguväärtused vastupidiseks)
 inverteeritud tulemus salvestatakse registrisse ???         ( INV RegA to REG )
   mnemokoodi võimalikud erijuhud / näited :        invAtoA    invAtoB    invAtoC    invAtoM
  1 1 1 0 1 ? ? ?  
  1 1 1 0 1 ? ? ?  
  E ? 
invBtoREG
1
 RegB inverteerimine  (kõik järguväärtused vastupidiseks)
 inverteeritud tulemus salvestatakse registrisse ???         ( INV RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :        invBtoA    invBtoB    invBtoC    invBtoM
  1 1 1 1 0 ? ? ?  
  1 1 1 1 0 ? ? ?  
  F ? 
decBtoREG
1
 RegB dekrementeerimine  (ühevõrra vähendamine)
 RegB dekrementeeritud tulemus salvestatakse registrisse ???         ( DEC RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :        decBtoA    decBtoB    decBtoC    decBtoM
  1 1 1 1 1 ? ? ?  
  1 1 1 1 1 ? ? ?  
  F ? 
incBtoREG
1
 RegB inkrementeerimine  (ühevõrra suurendamine)
 RegB inkrementeeritud tulemus salvestatakse registrisse ???         ( INC RegB to REG )
   mnemokoodi võimalikud erijuhud / näited :        incBtoA    incBtoB    incBtoC    incBtoM

L-CPU "oskab" ainult kahte adresseerimisviisi.   Pead oma programmis kasutama   (iga konkr. mällupöördumise juures)  õiget adresseerimisviisi   vastavalt oma ülesandepüstitusele :
otsene adresseerimine   vs   vahetu adresseerimine
LCPU omab 2 adresseerimisviisi:

OTSENE adresseerimine
Otsese adresseerimise korral pöördub käsk selle mälubaidi poole, mille aadress on käsule "teada" — ehk mällupöördumine toimub "(mälu)aadressi abil". Laboritöö3 CPU-mudelis asub otsepöördumise mäluaadress alati Registris M, kuhu programmeerija peab soovitud mäluadressi salvestama / laadima   enne kui otsepöörduskäsu täitmine protsessoris algab.
Otsene adresseerimine on seega "mällupöördumine koos konkreetse mäluaadressiga".
Olles ettevalmistav samm OTSESELE adresseerimisele, toimub   aadressi laadimine  Registrisse M ikkagi  "VAHETULT adresseeriva"  käsuga   LDtoM ;

Otsese adresseerimise korral võib  (siin laboritöös)  valida vabalt selle mälubaidi  (mäluaadressi), kust käsk loeb või kuhu kirjutab.
Saadaval on kogu vaba mälu — ehk kõik need mälubaidid, mis pole hõivatud  programmi endaga.
Mälust laaditav ehk "loetav" andmebait kirjutatakse eelnevalt mällu "käsitsi" (soovitud baiti   ehk   soovitud aadressile) — neid ei pea sinna viima/salvestama arvutiprogrammi  runtime.

VAHETU adresseerimine
Vahetu adresseerimise korral pöördub käsk iseenda asukoha suhtes järgmise mälubaidi poole   —   misjuhul mällu pöörduvale käsule ei anta ette/kaasa mitte mingit mäluaadressi.
Vahetu adresseerimine on seega "mällupöördumine ilma etteantud mäluaadressita":   mällupöörduv käsk (lugemine mälubaidist või kirjutamine mälubaiti) võtab vaikimisi (iseenda suhtes) järgmise "naaberbaidi".
Vahetu adresseerimine pöördub seega (mälus asuva) programmikoodi enda "sisse".

Laboritöö3 CPU-mudelis on otsese adresseerimise käskudeks kõik need, mis pöörduvad mällu Registris M asuva mäluaadressi kaasabil:
00001???   —   loeb ehk laadib Registrisse ??? suvaliselt etteantud mäluaadressilt;
00100000   —   salvestab Registrist C suvalisele etteantud mäluaadressile;
ja
vahetu adresseerimise käskudeks on:
00010???   —   loeb ehk laadib järgmisest mälubaidist Registrisse ???
00101000   —   salvestab Registrist C   käsu [00101000] enda asukoha suhtes   järgmisesse baiti ehk kohe järgmisele mäluaadressile;

nihkekäsud   ROL . . .   ROR . . .  
LCPU "oskab" ainult ringnihet, mitte aritmeetilist nihet.
Ringnihe (positiivsete arvude korral) osutub aritmeetilise nihkega samaväärseks, kui arv on paarisarv.
Mõtle järgi, mis toimub arvu väärtusega  kui kahendarvu kõik järgud 1 nihkuvad kaks korda suurema kaaluga naaberjärku?   Aga kui nad nihkuvad  kaks korda väiksema kaaluga naaberjärku?
Algoritmides / ülesannetes  kus on vaja arvväärtust korrutada suuremaks või jagada väikemaks   —   on selleks  LCPU-s saadaval ainult ringnihke käsud  ROL   ROR

muud täpsustused  Lab3  kohta :
☞   Lähteandmed (mida programm hakkab töötlema) võib Logisim-simulaatoris kirjutada mällu  käsitsi :   neid ei pea püüdma mällu ärakirjutada loodava arvutiprogrammi töötamise alguses  ehk  programmi  runtime-ga   (kuigi see on võimalik . . . )   Andmete   a s u k o h a   mälus ehk  mäluaadressi  võib valida vabalt :   saadaval on kogu vaba mälu, kus ei asu loodav programm ise.
☞   Kui vahetulemuste jaoks on ülesandes ettenähtud RegA või RegB, siis  töötlemise / arvutamise  lõpptulemuse  tohib  teda tekitav käsk  siiski kirjutada / salvestada "otse" registrisse RegC :   seda ei pea kirjutama esmalt registrisse RegA ega RegB, et see siis kohe järgmise käsuga sealt edasi kopeerida registrisse RegC.   Selline kopeerimine lisab programmi koosseisu  asjatuid / välditavaid  käske - kuid siiski ei langeta  Lab3  hindepunkte.