Tietokoneen toiminta, avoin yliopisto, kesä -99. Laskuharjoitus 3 (ma 9.8.), esimerkkivastaukset ------------------------------------------------ 1. a) Simuloi alla olevan ohjelman toimintaa. Mitä ohjelma tulostaa, jos annat syötteeksi syntymäkuukautesi järjestysnumeron? Entä mitä tapahtuu, jos annat syötteeksi negatiivisen luvun? Ohjelma tulostaa summan luvuista 1 .. järjestysnumero. Jos syöte ei ole positiivinen, annettu luku tulostuu sellaisenaan. Alku LOAD R1,=0 STORE R1,15 IN R2,=KBD STORE R2,14 LOAD R3,15 ADD R3,14 STORE R3,15 LOAD R4,14 SUB R4,=1 STORE R4,14 JPOS R4,4 LOAD R5,15 OUT R5,=CRT Loppu SVC SP,=HALT b) Ohjelmassa on laskettu ihan itse muuttujille osoitteet. Se voidaan kuitenkin jättää kääntäjän murheeksi. Muuta koodia siten, että siitä tulee 'luettavampi' ja siihen on jälkikäteen helpompaa lisätä uusia käskyjä. syöte DS 1 summa DC 0 Alku LOAD R1,=0 STORE R1,summa IN R2,=KBD STORE R2,syöte Jatka LOAD R3,summa ; tunnus tässäkin paikallaan myöh. hyppyä varten ADD R3,syöte STORE R3,summa LOAD R4,syöte SUB R4,=1 STORE R4,syöte JPOS R4,Jatka LOAD R5,summa OUT R5,=CRT Loppu SVC SP,=HALT c) Optimoi koodia, ts. poista lopputuloksen kannalta tarpeettomat käskyt. Käytetään ainoastaan kahta rekisteriä: Alku IN R2,=KBD LOAD R3,=0 Jatka ADD R3,R2 SUB R2,=1 JPOS R2,Jatka OUT R3,=CRT Loppu SVC SP,=HALT 2. a) Mitä seuraavat käskyt tekevät? Olkoon symbolin jatko arvo 100 ja symbolin a arvo 120. Rekisterissä R2 on 20. IN R1,=KBD Lukee näppäimistöltä kokonaisluvun rekisteriin R1. MUL R1,=7 Kertoo rekisterissä R1 olevan luvun seitsemällä. STORE R1,a Tallettaa rekisterin R1 arvon muistipaikkaan 120. HUOM: STORE-käskyn toisena operandina ei voi olla välitön operandi eikä rekisteri. JUMP @jatko(R2) JUMP on ehdoton hyppy, jolloin PC saa arvokseen toisen operandin mukaisen arvon. Indeksoidussa epäsuorassa muistiosoituksessa suoritetaan aluksi yhteenlasku rekisterin sisällön kanssa. Koska jatko+R2 == 100+20 == 120, hypätään muistipaikasta 120 löytyvään osoitteeseen. b) Eräiden rekisterien ja muistipaikkojen sisältö on seuraava: R1: 0, R2: 10, R3: 100 MP 100: 200, MP 110: 300, MP 200: 400, MP 300: 500, MP 400: 400 Mikä on R1:n sisältö seuraavien käskyn jälkeen? Oletetaan, että käskyt suoritetaan annetussa järjestyksessä. 1) LOAD R1, 100(R2) R1:300 (muistipaikasta 100+10 eli 110) 2) LOAD R1, =100(R3) R1:200 (arvo 100+100 eli 200, ei muistinoutoja) 3) LOAD R1, @R3 R1:200 (rekisterin R3 ilmoittamasta muistipaikasta) 4) LOAD R1, R3 R1:100 (rekisterin R3 arvo kopioidaan rekisteriin R1) HUOM: vastaava EI onnistuisi STORE-käskyllä - aina muistiin! 5) LOAD R1, @100(R2) R1:500 (muistipaikasta, jonka arvo löytyy muistipaikasta 100+10 eli 110; siis muistipaikasta 300) 6) LOAD R1, @400(R1) Muistipaikasta 400+R1 eli edellisen jälkeen muistipaikasta 900 löytyy muistiosoite, josta haetaan arvo R1:lle. Enempää ei tässä tiedetä. (Tätä ei ainakaan tarvitse kokeilla Koksi-simulaattorilla, sillä Koksi ei omista muistitilaa 900 tavun edestä...) 3. Kurssilla on sata oppilasta. Peräkkäisissä muistipaikoissa 100,...,199 on kunkin oppilaan pistemäärät. Kirjoita symbolisella konekielellä ohjelma, joka tulostaa oppilaiden pistemäärien keskiarvon. ; R1: yksitt. summattava pistemäärä (luetun muistipaikan arvo) ; R2: yhteissumma ; R3: seuraavaksi luettava muistipaikka (100-199) ; LOAD R2, =0 LOAD R3, =100 Toisto LOAD R1, @R3 ADD R2, R1 ADD R3, =1 COMP R3, =199 JNGRE Toisto DIV R2, =100 ; kokonaisjako ja aina sata oppilasta OUT R2, =CRT SVC SP, =HALT 4. Laadi symbolisella konekielellä ohjelma, joka lukee käyttäjän syöttämän positiivisen kokonaisluvun ja tulostaa sen kertoman. (Positiivisen kokonaisluvun kertomahan on sen ja sitä pienempien mutta nollaa suurempien kokonaislukujen tulo. Esim. viiden kertoma on 5*4*3*2*1 eli 120.) IN R1, =KBD LOAD R2, =1 ; tuloa kerrotaan tähän JZER R1, Tulosta ; nollan kertoma on suoraan tuo 1 JNEG R1, Lopeta ; negatiivinen luku ei kelpaa lainkaan Toisto MUL R2, R1 SUB R1, =1 ; syötetty luku toimii laskurina alaspäin JPOS R1, Toisto ; nollalla ei sovi enää mennä kertomaan Tulosta OUT R1,=CRT Lopeta SVC SP,=HALT 5. Nämä muistista löytyneet bittijonot on esitetty tässä heksadesimaali- järjestelmän lukuina. Esitä vastaavat käskyt TTK-91 symbolisella konekielellä (vihje: muunna ensin bittimuotoon). Mitä käskyt tekevät? Katso käskyrakenteen kuvaus sivuilta 48-49. *** Käskykoodiluettelo löytyy seuraavan dokumentin lopusta: *** *** http://www.cs.Helsinki.fi/~ahakkine/Tito/koksi.kaskyt *** 01 A0 00 A0 0 1 A 0 0 0 A 0 0000 0001 1010 0000 0000 0000 1010 0000 <-------> <-><-><-> <-----------------> oper Rj M Ri addr oper: 1 Rj: 5 M: 0 Ri: 0 addr: 160 -> STORE R5, 160 Tallettaa muistipaikkaan 160 rekisterin R5 sisällön. 18 47 00 01 oper: 24 Rj: 2 M: 0 Ri: 7 addr: 1 -> XOR R2, =1(FP) Suorittaa bittitason poissulkevan TAI -operaation R2:n ja seuraavan luvun kanssa: FP:n sisältö + 1 13 31 FF FF oper: 19 Rj: 1 M: 2 Ri: 1 addr: -1 -> MUL R1, @-1(R1) Kertoo rekisterissä R1 olevaa lukua ja hakee kertojan muistipaikasta MEM[MEM[R1-1]]. (Tällöin oikeastaan osoite on enemmänkin peräisin R1:stä. 'Virallisesti' -1 on kuitenkin se addr...) Kertolaskun tulos jää rekisteriin R1. 02 80 FF FE oper: 2 Rj: 4 M: 0 Ri: 0 addr: -2 -> LOAD R4, =-2 LOAD-käskyn suorituksen toteutuksesta kannattaa huomata seuraava: Koska käsky lataa nyt 16 bitin levyisestä addr-kentästä negatiivisen luvun rekisteriin R4, jonka leveys on 32 bittiä, tulee rekisterin yläbitit täyttää ykkösellä eikä nollalla. Näin siksi, että kyseessä ovat kahden komplementtiluvut. 1111 1111 1111 1111 1111 1111 1111 1110 = -2 -----yläbitit------ ------R4:stä------- 0000 0000 0000 0000 1111 1111 1111 1110 > -2 VÄÄRIN! -----yläbitit------ ------R4:stä------- 6b. Miten alkaisit itse toteuttaa Koksin kaltaista simulaattoria? Riittää kun lyhyesti selostat ohjelman toimintaideaa hyvin yleisellä tasolla ja kerrot jotain kaikkein keskeisimmistä tietorakenteista. Esimerkiksi seuraavasti. Tietorakenteita: Muistipaikat ja (useimmat) rekisterit voi toteuttaa kokonaislukutaulukkona; lisäksi tarvitaan muutama globaali muuttuja mm. tilarekisteriksi. Käskyt kannattaa ohjelmoida kukin omana funktionaan/metodinaan, joten jonkinlainen vastaavuustaulukko käskykoodien/-muistikkaiden ja ko. aliohjelmien välillä on myös hyvä olla. ALU:a ja keskeytyksiä/poikkeuksia ei tarvitse toteuttaa erikseen. Yksinkertaiset aritmeettiset toimenpiteet voi ohjelmoida suoraan aliohjelmiin ADD, MUL jne. Nollallajakotilanteissa DIV ja MOD voivat tulostaa virheilmoituksen itse. Koodia ei edes tarvitse purkaa bittitasolle asti ohjelman muistialueen alkuun, jos tehdään rajoitus, ettei ohjelmasta voi osoittaa koodin puolelle (ei itseään muuttavaa koodia tms.). Riittää, että simulaattori näyttelee toimivansa kuten vastaava 'oikea' kone. Sellaisia yksityiskohtia, jotka eivät kuitenkaan näkyisi käyttäjälle, ei missään nimessä ole välttämätöntä noudattaa orjallisesti.