130 likes | 269 Views
5.3.3 Koodin generointi. Koodin generointi tarkoittaa objektikoodin eli konekielisen ohjelman tuottamista. Generointi jakautuu kolmeen osatehtävään: Muistin varaaminen (memory allocation) ohjelman käyttämille tiedoille. Lähdekielistä ohjelmaa vastaavien konekielisten käskyjen muodostaminen.
E N D
5.3.3 Koodin generointi Koodin generointi tarkoittaa objektikoodin eli konekielisen ohjelman tuottamista. Generointi jakautuu kolmeen osatehtävään: • Muistin varaaminen (memory allocation) ohjelman käyttämille tiedoille. • Lähdekielistä ohjelmaa vastaavien konekielisten käskyjen muodostaminen. • Koodin optimointi.
5.3.3 Koodin generointi • Muistin varaaminen: • symbolitaulun perusteella lasketaan, montako muistipaikkaa ohjelman data-alue (= muuttujat, muut tunnukset ja tietorakenteet) tarvitsee • symbolitaulussa ilmoitetaan tunnuksen (ja vastaavien) nimen lisäksi sen tietotyyppi ja muistiosoite
5.3.3 Koodin generointi Esimerkki. MODULE Pythagoras (INTEGER x INTEGER y INTEGER z) RETURNS BOOLEAN RETURN x2 + y2 = z2 ENDMODULE SYMBOLITAULU (oletus: INTEGER varaa 32 bittiä eli 4 tavua, BOOLEAN 1 tavun)
Konekielisten käskyjen muodostaminen: • ohjelma jäsennetty => sen rakenne on jäsennyspuussa • käydään jäsennyspuun alkiot esijärjestyksessä läpi ja tuotetaan konekieltä, joiden käskyt toteuttavat syntaksiluokkien toiminnan • yleensä generoidaan symbolista konekieltä • muistipaikkoihin viitataan muuttujanimillä, ei todellisilla muistiosoitteilla • muuttujanimet korvataan muistiosoitteilla, kun ohjelma käännetään objektikoodiksi MODULE Generoi(jäsennyspuu P) Olkoon P = N(P1, ..., Pk) CASE N OF <moduuli>: generoimoduuli(P1, ..., Pk) <asetuslause>: generoiasetuslause(P1, ..., Pk) <joslause>: generoijoslause(P1, ..., Pk) <josmuutoin>: generoijosmuutoin(P1, ..., Pk) <whilelause>: generoiwhilelause(P1, ..., Pk) ... ENDCASE ENDMODULE
Esimerkki. Asetuslause x:=y o z, missä o on jokin operaattori (esim. yhteenlaskuoperaattori +). <asetuslause> → <tunnus>:=<lauseke> <lauseke> → <tunnus> <operaattori> <tunnus> <operaattori> → + | - | * / <tunnus> → <kirjain> | <kirjain> <tunnus> <kirjain> → a | b | c | ... Jäsennetään lause → jäsennyspuu <asetuslause> (<tunnus>(x),:=,<lauseke> (<tunnus>(y), <operaattori>(o), <tunnus>(z))) Esitystä voidaan sieventää: <asetuslause>(x,y,o,z)
5.3.3 Koodin generointi Esimerkiksi asetuslause x:=y o z puurakenteena: <asetuslause> (<tunnus>(x),:=,<lauseke> (<tunnus>(y), <operaattori>(o), <tunnus>(z))) <asetuslause> <:=> <tunnus> <lauseke> <tunnus> <operaattori> x <tunnus> o y z
5.3.3 Koodin generointi Esimerkiksi asetuslause x:=y o z sievennettynä puurakenteena (koodingenerointia varten): <asetuslause>(x y o z) <asetuslause> o z x y
Käännösmoduuli: MODULE Generoiasetuslause(x, y, o, z) Tulosta LOAD y CASE o OF '+' : Tulosta ADD z '-' : Tulosta SUBTRACT z '*' : Tulosta MULTIPLY z '/' : Tulosta DIVIDE z ENDCASE Tulosta STORE x ENDMODULE Muuttujat x, y ja z korvataan symbolitaulusta saatavilla osoitteilla ennen suoritusta
5.3.3 Koodin generointi Esimerkki ehtolauseesta: <oper> → > | < | = | ≠ <ehto> → <tunnus> <oper> <tunnus> IF-THEN-ELSE -rakenteen jäsennyspuu: <josmuutoin>(IF, <ehto>(...), THEN, <lause>(...), ELSE, <lause>(...))
Käännösmoduuli IF-lauseelle: MODULE Generoijosmuutoin(ehto-osa E, niin-osa P,muutoin-osa Q) Olkoon E = <ehto>(<tunnus>(x), <oper>(o),<tunnus>(y)) määrää nimiöt(tunnukset) a ja b (*jos ehto x o y on epätosi, ehto-koodista hypätään nimiöön a, muuten jatketaan seuraavasta:*) generoiehto(x,o,y,a) generoi(P) (*generoi niin-osa*) tulosta JUMP b (* ohita muutoin-osa*) tulosta a: NOP (* tyhjä käsky-jatketaan seuraavasta*) generoi(Q) (*generoi muutoin-osa*) tulosta b: NOP (* tyhjä käsky-jatketaan seuraavasta*) ENDMODULE • muuttujat x, y ja z korvataan symbolitaulusta saatavilla osoitteilla
MODULE generoiehto(x, o, y, a) (* hypätään aina nimiöön a (muutoin-osaan), jos ehto ei toteudu *) CASE o OF '>',’>=’: tulosta LOAD x SUBTRACT y (*jos y>x:*) JUMPNEG aIF o = ’>' THEN tulosta(*jos y=x:*) JUMPZERO a ENDIF ’<',’<=': tulosta LOAD y SUBTRACT x (*jos x>y:*) JUMPNEG aIF o =’<’ THEN tulosta(*jos x=y:*) JUMPZERO a ENDIF '=': tulosta LOAD x SUBTRACT y (*jos y>x:*) JUMPNEG a LOAD y SUBTRACT x (*jos x>y:*) JUMPNEG a ‘<>’: tulosta LOAD x SUBTRACT y (*jos y=x:*) JUMPZERO a ENDCASE ENDMODULE
3. Koodin optimointi • mekaanisesti generoitua koodia voidaan yleensä parantaa • poistetaan ne konekielen pätkät, jotka eivät vaikuta senhetkiseen ohjelman tilaan • esim. IF x>y THEN x:= x-y ELSE x:=0 ENDIF LOAD x SUBTRACT y(y>x) JUMPNEG a(y=x) JUMPZERO a(niin) LOAD x SUBTRACT y(x:=x-y) STORE x(ulos) JUMP ba: NOP(muutoin) LOADI 0 STORE xb: NOP turhia!
5.3.4 Symbolinen konekieli • jos ohjelmoi konekielellä • on helpompaa käyttää nimiöitä hyppyosoitteina kuin muistipaikkojen numero-osoitteita • esim. LOAD b2, ei LOAD 15 • helpompaa käyttää käskysanoja kuin käskykoodeja • LOAD b2: 0001 0000 0000 1111 (0001=LOAD:in käskykoodi, loput-operandi) • nimiöt (tunnukset) kerätään symbolitauluun • assembleri (eng. to assemble = koota, kerätä): • helpottaa konekielellä ohjelmointia • kääntää symbolisen konekielen oikeaksi konekieleksi • sijoittaa nimiöiden tilalle oikeat numeeriset osoitteet • korvaa käskysanat käskykoodeilla • käännösprosessi on suoraviivainen: jokainen symb.konekielen rivi vastaa oikean konekielen riviä • tuotetussa objektikoodissa osoitteet suhteellisia • kuvitellaan, että ohjelma datoineen alkaa osoitteesta 0 • kaikki osoitteet lasketaan siitä osoitteesta • lataaja: • korvaa suhteelliset osoitteet todellisilla osoitteilla: • esim. ohejlmalle varataan muistialue 2000-2050 • suht. osoitteet muutetaan todellisiksi lisäämäällä niihin arvo 2000 • => muistinhallinta • lataaja on käyttöjärjestelmän osa