Käskysykli¶
Osaamistavoite: Konekielen käskyn suorittaminen sekventiaalisessa prosessorissa.
y86-prosessorista esitellään kurssilla kaksi versiota, joista ensimmäinen, tässä materiaalissa esitettävä, perustuu sekventiaaliseen käskyn suoritukseen. Tämä tarkoittaa sitä, että prosessorissa jokainen käsky suoritetaan kokonaisuudessaan yhden kellojakson aikana. Käskyn suoritus jaetaan ao. mukaisesti pienempiin vaiheisiin prosessorin osajärjestelmissä, jotka suorittavat käskyn peräkkäin saman kellojakson aikana. Nyt käskystä riippuen siis eri osajärjestelmät ovat aktiivisia suorituksen eri vaiheissa.
Suorittimen sisäisen toimintalogiikan suunnittelussa on edullista, että käskysykli on sama kaikille käskyille. Tällöin toteutus yksinkertaistuu, logiikan kompleksisuus ja komponenttien määrä saadaan minimoitua. Toki tämä on moderneissa suorittimissa toooodella hidas tapa suorittaa ohjelmakoodia, mutta sekventiaalinen käskyn suoritus on oleellista ymmärtää ennenkuin siirrytään tehokkaampiin toteutuksiin.
Käskyn suoritus¶
Suorittimissa käskyn suoritukseen liittyy rekisteri nimeltä ohjelmalaskuri/PC (engl. program counter), jossa säilytetään nykyisen käskyn muistiosoitetta. Josta osoitteesta siis käsky alunperin haettiin muistista suorittimelle. Kun ohjelman suoritus etenee, rekisterissä oleva muistiosoite aina päivittyy.
Käskyn suorittamisessa, käskysyklissä on sekventiaalisessa y86:sessa kuusi vaihetta. Käytämme vaiheista (paremman puutteessa) niiden englanninkielisiä nimityksiä:
- Fetch Käsky noudetaan muistista PC-rekisterin osoittamasta paikasta ja se tulkitaan (mikro-arkkitehtuurissa), ts. kaivetaan operaatiokoodi ja operandit.
- Decode Luetaan arvot operandien viittaamista rekistereistä ja asetetaan ne ALU:lle valmiiksi.
- Execute Suoritetaan käskyn operaatiokoodin mukainen aritmeettis-looginen operaatio operandeille / lasketaan muistiosoite muistiviittausta varten / päivitetään pino-osoitin. ALUn yksinkertaista neljää operaatiota siis hyödynnetään monipuolisesti.
- Memory Jos käskyssä on muistiosoitus, luetaan tai kirjoitetaan annetusta muistiosoitteesta.
- Write back ALUn operaation tulokset kirjoitetaan tulosrekisteriin.
- PC Update Päivitetään PC-rekisteriin seuraavan käskyn muistiosoite.
Tätä käskysykliä sitten prosessorimme jauhaa loputtomiin, ellei poikkeusta tule tai ohjelman suoritus lopu. Execute-vaihe on pakollinen jokaisessa käskyssä, mutta kaikki käskyt eivät aina suorita kaikkia vaiheita, jos ne eivät ole tarpeen käskyssä. Esimerkiksi, jos ei ole muistiosoitusta niin sitä vaihetta ei suoriteta.
Alla yleiskuvaus y86:sen käskysyklistä. Huomataan, että suorittimen sisäisesti eri vaihden tulokset tallentuvat sisäisiin rekistereihin ja ohjaus kulkee signaaleina osajärjestelmien välillä. Signaali on tässä abstraktio, jossa voi myös kulkea dataa.
Osajärjestelmät¶
Seuraavaksi esitetään yleinen kuvaus mitä käskysyklin jokaisessa vaiheessa tapahtuu eri osajärjestelmissä. Tarkempi kuvaus kaikkine (ohjausosan yms) signaaleineen löytyy oppikirjasta, mutta tämä taso riittää meille.
Kuvauksessa esitetään rekisteri- ja muistisiirtoja, joiden syntaksi on seuraava:
R[x]
tarkoittaa, että luetaan rekisterin x arvo / kirjoitetaan arvo rekisteriin xM[x]
tarkoittaa, että luetaan muistpaikan x arvo / kirjoitetaan arvo muistipaikkaan x
Kuvauksen rinnalla materiaalissa esitetään mitä esimerkkikäskyssä tapahtuu:
# Lähtötilanne PC=0x2c %rbx=0x3 %rcx=0x4 # Suoritetaan käsky addq %rbx,%rcx
Fetch¶
Tässä vaiheessa käsky noudetaan muistista PC-rekisterin näyttämästä paikasta.
Nyt kontrolliosa tulkitsee käskyn seuraavat arvot:
- Operaatiokoodi
icode
: käskyryhmäifun
: alifunktio, operaatiokoodin tarkennus- Operandit
rA
jarB
ovat0x0-0xE
jos operandit ovat rekistereitä tai0xF
jos operandi ei ole rekisterivalC
sisältää vakioarvo tai muistiosoitteen, jos sellainen käskyssä on- Seuraavan käskyn osoite:
valP
on nykyinen PC + luetun käskyn pituus tavuina - Jos operaatiokoodi tai muistiosoite ovat virheellisiä, asetetaan poikkeustilat
INS
taiADR
ja ohjelman suoritus päättyy.
Esimerkkikäsky
addq %rbx,%rcx
eli konekielellä kaksi tavua 0x60 ja 0x31, joka haettiin osoitteesta 0x2c
. # Käskyn ensimmäinen tavu (PC=0x2c): icode:ifun <- M[0x2c] = 60 icode = 6 # Aritmeettiset operaatiot ifun = 0 # Funktio 0, yhteenlasku # Käskyn toinen tavu (PC+1=0x2d): rA:rB <- M[0x2d] = 31 rA = 3 # Rekisterin %rbx numerokoodi rB = 1 # Rekisterin %rcx numerokoodi # Seuraava PC:n arvo: valP <- PC + 2 = 0x2c + 0x2 # Käskyn pituus valP = 0x2e
Decode ja Write-back¶
Tässä vaiheessa tehdään kaksi toisistaan poikkeavaa toimintoa samalla osajärjestelmällä, koska molemmissa vaiheissa käsitellään rekistereitä. Decode-vaiheessa käskyn operandit asetetaan ALUlle valmiiksi käskyn suorittamista varten. Write-back -vaiheessa ALUn operaation tulos viedään tulosrekisteriin.
Kontrolliosassa on neljä rekisteriä, joihin asetetaan luku- ja kirjoitusoperaatioiden kohderekisterien koodit.
- Input
srcA
: käskyn ensimmäinen operandirA
- Input
srcB
: käskyn toinen operandirB
- Output
dstE
: käskyn suorituksen tulosrekisterirB
- Output
dstM
: muistiin kirjoitettava arvorA
Decode-vaiheessa asetetaan (
icode
:sta riippuen) ALU:lle input-arvot (valA
ja valB
) käskyn rekisterien rA
ja rB
arvoista. Write back-vaiheessa (
icode
:sta riippuen) käskyn tulos valE
kirjoitetaan rekisteriin rB
tai tai muistiosoitteesta haettu arvo valM
rekisteriin rA
. Esimerkkikäsky
addq %rbx,%rcx
Decode-vaiheessa.valA <- R[rA] # Luetaan rekisterin rA (siis %rbx) arvo. valA = 0x3 # .. joka on 0x3 valB <- R[rB] # # Luetaan rekisterin rB (siis %rcx) arvo. valB = 0x4 # .. joka on 0x4
Esimerkkikäsky
addq %rbx,%rcx
Write back-vaiheessa.# Viedään ALUN operaation tulos rB:n osoittamaan rekisteriin (%rcx) R[rB] <- valE # valE:sta saadaan ALUn operaation tulos R[rB] = 0x7 # .. joka on 0x7
Execute¶
Edellisessä vaiheessa asetimme operandien arvot valmiiksi ALUlle. Nyt sen ei tarvitse tietää mitä ja mistä arvot, ovat vaan se voi vain suorittaa niille halutun operaation.
y86-64:sen ALU osaa vain neljä operaatiota, jotka on kerrottu
icode:ifun
-inputeissa Fetch-vaiheessa: yhteenlasku, vähennyslasku, JA-operaatio ja ERI-operaatio. Tarvitaan vielä kontrolliosa asettamaan varsinaiset sisääntulot ALU:lle
aluA
ja aluB
, koska inputit voivat olla rekistereitä (valA
ja valB
) tai vakioarvo valC
(Fetch-vaiheesta). Nyt kontrolliosa valitsee kytkettävät inputit icode
:n arvosta riippuen. Kun ALU:n operaation on suoritettu, operaation tulos tallentuu
valE
:hen, jossa voi käskystä riippuen olla myös muistiosoite. Lisäksi ALU asettaa tilabittien arvot tilarekisteriin. Esimerkkikäsky
addq %rbx,%rcx
valE <- valB + valA # %rbx ja %rcx valE = 0x4 + 0x3 = 0x7 cnd <- CC # Asetetaan tilaliput
Itseasiassa, ALUn operaatioista yhteenlasku on käytetyin operaatio, jolla voidaan toteuttaa hyvin erilaisia käskyjä yllättävän yksinkertaisesti, kts. esimerkit materiaalin lopussa..
Memory¶
Tässä vaiheessa joko luetaan dataa muistista rekisteriin tai kirjoitetaan rekisteristä dataa muistiin. Operaatio kerrotaan jälleen kerran
icode
:ssa. Huomataan, että muistisijoitukset menevät siis ALUn ja rekisterien kautta, eikä operoida suoraan muistiin..Kontrolliosa asettaa muistiosoitteen joko:
- Yleisesti
valE
:sta, joka laskettiin Execute-vaiheessa - Pinon käyttö: muistiosoite saadaan
valA
:sta, eli minne se luettiin Decode-vaiheessa (%rsp-rekisteristä.
Kirjoitettava data valitaan operaatiokoodin mukaan joko:
- Yleisesti
valA
:sta (Decode-vaiheesta) - Poikkeus:
call
-aliohjelmassakutsussavalP
:stä (eli seuraavan käskyn osoite) kirjoitetaan pinoon, jotta paluu onnistuu.
Muistista luettu data/osoite tallentuu
valM
:ään. (Kuvassa KL=kontrollilogiikka).
Esimerkkikäskymme ei tee muistivaiheessa mitään. Materiaalin lopussa muita esimerkkejä missä tämä osaoperaatio suoritetaan.
PC Update¶
Tämän jälkeen tarvitsee enää päivittää
PC
-rekisterin arvo, josta seuraava käsky noudetaan Fetch-vaiheessa. Uusi osoite voi olla joko:
- Yleisesti
valP
- Aliohjelmasta paluu:
ret
-käskyssävalM
, koska osoite haettiin pinosta Memory-vaiheessa - Ehdolliset hypyt: operaatiokoodin mukaan joko
valC
taivalP
. Nyt siisicode
jacnd
-tilabitit kertovat suoritetaanko hyppy.
(Kuvassa KL=kontrollilogiikka)
Esimerkkikäsky
addq %rbx,%rcx
# Nyt PC:tä piti kasvattaa 2 tavua PC <- valP # 0x2c + 2 PC = 0x2e
Käskyn suoritusesimerkkejä¶
Kuvassa esimerkin vuoksi osajärjestelmien toiminta eri tyyppisissä käskyissä.
Kuvasta nähdään miten ALU:n operaatiota käytetään eri käskyissä:
addq
: Laskutoimitus ja asetetaan tilabititirmovq
: Siirto-operaatio yhteenlaskun (nollan kanssa) avulla.rmmovq
: Lasketaan muistiosoite, josta luetaan / kirjoitetaan dataa.popq
: Haetaan pinosta arvo ja muutetaan pino-osoitetta. Nykyinen muistiosoite ja sanan pituus.jne
: Hyppy, jossa tarvitsee lukea tilabitit
Lopuksi¶
Prosessorin toiminnan ymmärtäminen on avain koko tietokoneen toiminnan ymmärtämiseen. Tässä kappaleessa esittelimme yleisesti sekventiaalisen y86-64:sen toiminnan käskyjen suorituksessa.
Sekventiaalisen suorittimen heikkoutena on, ettei siinä käskyn suoritusaikaa voi optimoida, vaan kaikki käskyt suoritetaan hitaimman mukaan. Ts. kellojakso on niin hidas, että kaikki käskyt ehditään suorittaa ja tyypillisesti muistia käyttävät operaatiot ovat hitaimpia. Vaihtoehtoisesti sisäistä toimintaa voisi optimoida monimutkaisemmalla digitaalilogiikan toteutuksella, josta lisää myöhemmin.. Ja, sen sijaan että lisättäisiin hardikseen komponentteja tai digitaalilohkoja, voi olla halvempaa tehdä sama operaatio jopa ohjelmallisesti! Ohjelmistolla on myös helpompi hoitaa käskyihin liittyviä erikoistilanteita.
Seuraavissa luentomateriaalin kappaleissa esitetään tehokkaampia toteutustapoja y86-prosessorille ja suorittimille yleisesti.
Anna palautetta
Kommentteja materiaalista?