Laitteistonläheinen ohjelmointi 4 op Luennoija: Pertti Lehtinen Luennot: Perjantai 12-14 TB104 Esitiedot: Mikroprosessorit Perusohjelmointikurssi Kurssin osat: luennot, harjoitustyö, tentti Materiaali: luentomateriaali
Kurssin tavoite Oppia ymmärtämään konekielisiä ohjelmia Mitä on ohjelma prosessorin tasolla Miten ohjelma käyttää koneen resursseja Saada käsitys ohjelman luontiprosessista Työkalut ja niiden tehtävät Tutustua lausekielten perusrakenteiden toteutukseen konekielitasolla Mitä kääntäjä tuottaa?
Miksi? Konekielinen ohjelmointi, kääntäjän toteuttaminen Oleellista jos teet Laiteohjainta Käyttöjärjestelmää Sulautettua järjestelmää Suunnittelet suoritinta
Luennot Prosessoriarkkitehtuurit Käskyt, osoitusmuodot, tietotyypit Kääntäminen Perusrakenteet, aliohjelmat, tietotyypit Muistin käyttö Yhdistely, kirjastot, ohjelman sijoittelu, dynaaminen muisti Prosessorin kontrolli Cache, MMU, kontekstin vaihto, yms. Oheislaitteet ja väylän ohjaus Muuta Erikoiskäskyt, Virtualisointi, jne...
Prosessoriarkkitehtuuri Perinteisesti fetch-decode-execute Käskyt noudetaan ja suoritetaan järjestyksessä Ohjelmoijan perinteinen ajattelu, yhä voimissaan
Von-Neumann arkkitehtuuri CPU käsittelee muistissa olevan ohjelman käskyjen mukaisesti muistissa oleva dataa Yhteinen koodi- ja data muisti Von Neumann -pullonkaula --> muistiväylä Harvard-arkkitehtuuri Erillinen ohjelma- ja datamuisti (väylä) Muita vaihtoehtoja VLIW, TTA, SIMD
Prosessorin rakenne Toimintayksiköitä Laskentayksiköitä, yksi tai useampia Kokonaislukuyksiköt Liukuluku yksiköt Muut? (SSE, MMX, VIS,...) Ohjausyksikkö Hyppy-yksiköt Muistiyksiköt Muistiviittaukset (data), käskynnouto
Nykypäivän arkkitehtuurit Erilliset cachet, yhteinen keskusmuisti Siis sovellettu harvard arkkitehtuuri Liukuhihnoitettu suoritus Viivästetty lataus, viivästetty hyppy, scoreboarding Rinnakkaiset laskentayksiköt out-of-order-execution
Prosessori arkkitehtuuri Sananleveys Käskykoodi, data Rekisterien määrä Akku koneet vs. rekisterikoneet Operandien määrä Nolla, yksi, kaksi, kolme Osoitustavat Perinteinen vs. load-store
Prosessori arkkitehtuuri Käskykanta Mitä sillä voi tehdä? Tietotyypit Millä se voi operoida? Osoitusmuodot Missä ne voivat olla?
Käskykanta Aritmeettisloogiset operaatiot Add, sub, neg, mul, div And, or, xor, complement,... Tst, cmp Siirtokäskyt Move, load, store kontrollinsiirto Bra, jmp, call, ret
Aritmetiikka Ainakin kokonaisluvuille Add, sub vähintään Nykyään myös mul ja div Liukulukuaritmetiikka Fadd, fsub, fmul, fdiv Joskus myös sin, cos,...
Loogiset operaatiot Peruslogiikka And, or ja complement usein myös xor Loogiset käskyt ovat bitwise käskyjä eivät siis totuusarvoisia
Loogiset operaatiot Peruslogiikka And, or ja complement usein myös xor Loogiset käskyt ovat bitwise käskyjä eivät siis totuusarvoisia
vertailut Vertailukäskyt Yleensä ainakin cmp, (compare) Joskus myös tst, (test, eli vertaa nollaan) Liittyvät ehdollisiin hyppyihin Asettavat tilaliput tai jonkun tilatiedon
Siirtokäskyt Rekisterisiirrot Move Muistista nouto Load Muistiin talletus Store
Kontrollin siirto Ehdottomat hypyt Jmp, bra Ehdolliset hypyt Beq, bne,... Aliohjelmakutsu ja -paluu Call, ret Palvelukutsut ja virhekäsittelyt Trap, svc, syscall,...
Ehdolliset hypyt Tilalippujen perusteella (IA-32, MC680X0, Sparc) Liput asettuvat Vain vertailukäskyillä (Sparc) Vertailu- ja aritmeettisloogisillakäskyilla (IA-32) Vertailu-, aritmeettisloogisilla- ja siirtokäskyillä (MC680x0) Lippurekisterien sisällön perusteella (PowerPC) Yleisrekisterien sisällön perusteella (MC88000, Alpha)
Tilaliput Zero Ilmaisee, onko tulos nolla Sign Tuloksen etumerkki Carry, overflow Etumerkitön ylivuoto, etumerkillinen ylivuoto, lainaus Joskus myös muita lippuja
Lipuista carry/borrow/extend Laajennetussa aritmetiikassa tarpeellinen Add-with-carry, add-with-extend,... Tavallinen aritmetiikka etumerkillistä Osoitteilla laskenta etumerkitöntä Etumerkin käsittely näkyy vain vertailtaessa ja kerto/jakolaskussa
Siirtokäskyt Siirrot rekisterien välillä Lataukset muistista/muistiin Oleellisen tärkeitä nykyään käytetyissä load-store arkkitehtuureissa
Aliohjelmakutsu Hyppy paluuosoitteen talletuksella Talletus (laitteisto)pinoon (perinteisesti) IA-32, MC680X0,... Automaattisesti mahdollistaa sisäkkäiset kutsut Talletus yleisrekisteriin (RISC-arkkitehtuurit) Sparc, MC88000,... Ohjelmallinen pino tarpeen sisäkkäisten kutsujen mahdollistamiseksi Paluu erikoiskäskyllä tai epäsuoralla hypyllä
Muut käskyt Cachen ohjaus Mmun ohjaus Keskeytysten hallinta käskykantalaajennukset
Millaisia operandeja Kokonaisluvut Liukuluvut Kiinteän pilkun luvut Totuusarvot merkkijonot Pixelit, bitit, yms
kokonaisluvut 8, 16, 32 vai 64-bittiä? Etumerkillinen vai etumerkitön? Kahden komplementtiesitys käytössä
liukuluvut 32-bittinen (float) Etumerkki, 8-bittinen exponentti, 23-bittinen mantissa Normalisoitu esitys, ns. hidden bitti käytössä 64-bittinen (double) Etumerkki, 11-bittinen exponentti, 52-bittinen mantissa Normalisoitu esitys, ns, Hidden-bitti käytössä 80-bittinen (extended) Liukuluku yksikön väliaikainen esitysmuoto, käytössä sisäisesti
Normalisoitu liukuluku Ensin etumerkki Sitten exponentti, sitten mantissa Käytetty exponentti valitaan niin, että ensimmäinen mantissan merkitsevä bitti on yksi, -> tämä ns. hidden bit voidaan jättää pois Exponentti skaalataan 127:llä, välille 0-255 (32- bittiset), 1023:lla välille0-2047 (64-bittiset)
Kiinteänpilkun luvut Kokonaisluvuon tulkinta Sovitaan lukuun pilkun paikka Operoidaan kuten kokonaisluvuilla Korjataan kerto- ja jakolaskujen yhteydessä Käytetään liukulukujen sijasta, jos lukualue riittää Esitä eurot sentteinä (kaksi desimaalia) Fraktaaleissa mandelbrot tarvii kokonaisosaa vain 2.0:n asti
totuusarvot Testit palauttavat tiedon tilalipuissa Yleensä ei sidottu arkkitehtuurissa Totuusarvon esitys ohjelmoijan valittavissa C-kielen valinta 0 <=> false, 1 <=> true, kun luodaan 0 <=> false, ei 0 <=> true, kun testataan
Merkkijonot Jotkut arkkitehtuurit sisältävät merkkijonojen käsittelyyn suunniteltuja käskyjä Merkkijono <=> tavujono, lohko Harvinaisia ja usein vähän käytettyjä
Muut tietotyypit Lisäksi voi tavata operaatioita muilla tietotyypeillä Bitti-operaatioita Pixelit 32-bittinen (8+8+8+8 bittiä)rgb. BCD-luvut
Missä operandit ovat Implisiittisiä vai explisiittisiä? 0, 1, 2 tai 3-operandi arkkitehtuuri Rekistereissä vai muistissa? Hierarkkinen muisti Rekisteri (cachet) keskusmuisti - (massamuisti) Load-store -arkkitehtuuri
Missä operandit ovat? 0-operandi arkkitehtuuri Pinoarkkitehtuuri Käskyssä kerrotaan vain operaatio, operandit implisiittisiä, samoin tuloksen sijoitus Käytetty joissakin vanhemmissa arkkitehtuureissa Tavanomainen virtuaalikoneena, koodingenerointi helppoa
esimerkki Laskemme e = a/b + c*d load a -- instr/address 3 iar load b -- instr/address 3 iar div -- instr 4 irrw load c -- instr/address 3 iar load d -- instr/address 3 iar mul -- instr 4 irrw add -- instr 4 irrw store e -- inst/address 3 iaw Kaikkiaan 13 sanaa, 13+10+4 jaksoa
Missä operandit ovat 1-operandi arkkitehtuuri Käskyssä kerrotaan yksi operandi, toinen operandi ja tuloksen sijainti implisiittisiä ns. akkukone Useimmat 8-bittiset arkkitehtuurit (Z80, 6502, MC6800, 8085, myös 8086 )
esimerkki Laskemme e = a/b + c*d ld a -- inst/adr 3 iar div b -- inst/adr 3 iar st tmp -- inst/adr 3 iaw ld c -- inst/adr 3 iar mul d -- inst/adr 3 iar add tmp -- inst/adr 3 iar st e -- inst/adr 3 iaw Kaikkiaan 21 sanaa, 14+5+2 jaksoa
Missä operandit ovat 2-operandi arkkitehtuuri Käsky spesifioi kaksi operandia, joista toinen tulkitaan myös tuloksen sijaintipaikaksi Ns yleisrekisterikone mm. MC680x0, ia-32 tällaisia Operandit rekister(e)issä tai muistissa
esimerkki Laskemme e = a/b + c*d mov a,r0 --inst/adr 3 iaar div b,r0 -- inst/adr 3 iaar mov c,r1 --inst/adr 3 iaar mul d,r1 -- inst/adr 3 iaar add R1,R0 --inst 1 i mov R0,e --inst/adr 3 iaaw Kaikkiaan 16 sanaa, 16+4+1 jaksoa
Missä operandit ovat 3-operandikone Käsky spesifioi erikseen kaksi lähdeoperandia ja kohdeoperandin Yleinen RISC-arkkitehtuureissa Operandit yleensä rekisterioperandeja (tai vakioita)
esimerkki Laskemme e = a/b + c*d ld R7,#base -- inst 2 ii ld R0,a[R7] -- inst 1 ir ld R1,b[R7] -- inst 1 ir div R0,R1,R2 -- inst 1 i ld R2,c[R7] -- inst 1 ir ld R3,d[R7] -- inst 1 ir mul R2,R3,R4 -- inst 1 i add R4,R2,R5 -- inst 1 i st R5,e [R7] -- inst 1 iw Kaikkiaan 8 sanaa, 10+4+1 jaksoa
Mistä rakenne määräytyy Suunnittelijan valinnat Käskykoodin pituus (8, 16, 32, tai muuta) Kiinteä pituus, vaihtuva pituus Rekisterien määrä (4, 8, 16, 32, 256)?
Muistiosoitus Joko suoraan operandissa Tai erikseen load- ja store käskyissä Perinteiset arkkitehtuurit (ia-32, mc680x0) sallivat operandit suoraan muistiin Uudet arkkitehtuurit (sparc, arm, powerpc) load-store -arkkitehtuureita, joissa muistiviittaukset vain load- ja storekäskyillä
Osoitusmuodot Suorat osoitukset Absoluuttinen osoite Suhteellinen osoite rekisteri Hyppykäskyissä yleisiä Jmp, bra, call, ret
Osoitusmuodot Epäsuorat osoitukset Osoite rekisterissä Vakio indeksi + kantaosoite rekisterissä Indeksi rekisterissä + kantaosoite rekisterissä Sparc-arkkitehtuurissa vain nämä dataa osoitettaessa Joskus myös monimutkaisempia Vakio+indeksirekisteri+kantarekisteri Joskus myös moninkertaista epäsuoruutta
Osoitusmuodot Autoinkrementointi Rekisteriä kasvatetaan viittauksen yhteydessä Autodekrementointi Rekisteriä vähennetään viittauksen yhteydessä Implisiittisesti pinon yhteydessä (ia-32) Explisiittisesti (mc680x0, pdp-11,... ) Writeback indeksoitaessa (arm)