Luento 10
Käännös, linkitys ja lataus
| Käännös | |
| Linkitys | |
| Dynaaminen linkitys | |
| Lataus | |
Lausekielestä suoritukseen (3)
| Jollain ohjelmointikielellä kuvattu eheä kokonaisuus, joka halutaan aina kääntää yhdessä | ||
| kaikki yhteen liittyvät aliohjelmat | ||
| olioperustainen luokka | ||
| Liian suuri kokonaisuus? | ||
| turhaa aikaa kääntämiseen joka muutoksen jälkeen | ||
| Liian pieni kokonaisuus? | ||
| turhaa aikaa liitoksien suunnitteluun ja toteutukseen muiden moduulien kanssa | ||
| Käännösyksikön ohjelmointikieli ei ole tärkeä | ||
| niiden sitominen yhteen tapahtuu objektimoduulien tasolla | ||
Assembler-kielinen käännösyksikkö (2)
| Käännösyksikkö voi olla myös suoraan k.o. koneen symbolisella konekielellä kirjoitettu | ||
| suoraan käsin | ||
| kääntäjän generoimana korkean tason kielestä |
||
| Käännöksen tekee assembler-kääntäjä tavallisen kääntäjän asemesta | ||
| yleensä osa tavallista kääntäjää | ||
| Konekielinen koodi | ||
| moduulin sisäiset viitteet paikallaan
(lineaarisessa muistiavaruudessa) |
||
| moduulin ulkopuoliset viitteet merkitty | ||
| Linkitystä varten: | ||
| tiedot niiden osoitteiden sijainneista, jotka täytyy päivittää, kun moduulin osoiteavaruus yhdistetään jonkin toisen moduulin osoiteavaruuden kanssa linkityksessä |
||
| tiedot viittauksista moduulin ulkopuolelle | ||
| tiedot kohdista, joista tähän moduuliin saa viitata ulkopuolelta | ||
| symbolitaulu | ||
| Kääntäjä generoi | ||
| Ylläpidetään linkityksen aikana | ||
| Joskus ylläpidetään myös latauksen jälkeen virheilmoitusten tekemistä varten | ||
| ohjelmien kehitysympäristöt ylläpitävät symbolitaulua koko ajan | ||
| Jätetään pois valmiista ohjelmasta | ||
| vie turhaa tilaa | ||
| Pascal lauseke: N := I+J; | |
| C lauseke: N = I+J | |
| Java lauseke: N = I+J; |
(Assembler) kääntäjän ohjauskäskyt (4)
| Eivät varsinaista koodia | ||
| niistä ei tule konekäskyjä | ||
| Ohjaavat käännöstä | ||
| Helpottavat ohjelmointia | ||
| Usein toistuville koodisarjoille
annetaan nimi Þ makro |
||
| Makroilla voi olla parametreja | ||
| useimmiten nimiparametreja (call-by-name) | ||
| Makrot käsitellään ennen kääntämistä | ||
| eivät kuulu konekieleen | ||
| makron ”kutsu” (käyttö) korvataan makron rungolla | ||
| Esimerkkejä | ||
| swap | ||
| aliohjelmien prologi ja epilogi | ||
| itse tehdyt, kääntäjän käyttämät | ||
| Erot aliohjelmiin | ||
| Vakioita | |
| Niin suuria, että eivät mahdu
konekäskyn vakio-osaan ... |
|
| ... tai muuten vain halutaan pitää
datan joukossa eikä käskyjen yhteyteen talletettuna |
|
| Niitä ei saisi muuttaa |
| Korkean tason kielissä kaikki isot vakiot ovat literaaleja | |||
| kääntäjän pitäisi estää literaalien muuttamisen | |||
| literaalia ei saisi välittää viiteparametrina | |||
| aliohjelma voisi muuttaa sen arvoa? | |||
| Myös joissakin assemblerkielissä literaalien implisiittinen (automaattinen) määrittely | |||
| helpommin luettavaa koodia |
|||
| literaalin 234567 tilanvaraus automaattisesti | |||
| 1. vaihe: | |||
| laske käskyjen tilanvaraukset | |||
| ttk-91 helppoa, koska kaikki käskyt 4 tavua! | |||
| generoi symbolitaulu | |||
| arvot, arvon vaatima tavumäärä | |||
| uudelleensijoitustiedot (omana tauluna?) | |||
| generoi tai käytä muita tauluja | |||
| literaalitaulu (tilanvaraus lopuksi) | |||
| kääntäjän ohjauskäskytaulu | |||
| operaatiokooditaulu | |||
| 2. vaihe | |||
| generoi lopullinen objektimoduuli |
|||
| tulosta symbolinen konekielinen listaus | |||
| generoi taulut linkitystä varten | |||
| osana objektimoduulia | |||
| anna virheilmoitukset | |||
| 3. vaihe | |||
| koodin optimointi | |||
| voi olla oikeasti ennen 2. vaihetta tai sen yhteydessä | |||
Esimerkki: TTK-91 Assembler käännös, 1. vaihe
| s DC 0 | ||
| i DC 1 | ||
| 0: Taas LOAD R1, i | ||
| 1: MUL R1,R1 | ||
| 2: ADD R1, s | ||
| 3: STORE R1, s | ||
| 4: LOAD R1, i | ||
| 5: ADD R1, =1 | ||
| 6: STORE R1, i | ||
| 7: COMP R1, =21 | ||
| 8: JLES Taas | ||
| 9: SVC SP, =HALT | ||
| s DC 0 | ||
| i DC 1 | ||
| 0: Taas LOAD R1, i | ||
| 1: MUL R1, R1 | ||
| 2: ADD R1, s | ||
| 3: STORE R1, s | ||
| 4: LOAD R1, i | ||
| 5: ADD R1, =1 | ||
| 6: STORE R1, i | ||
| 7: COMP R1, =21 | ||
| 8: JLES Taas | ||
| 9: SVC SP, =HALT | ||
| 10: 0 ; siis s = 10 | ||
| 11: 1 ; i = 11 | ||
| Moduulin otsakeosa | ||||
| moduulin nimi | ||||
| linkittäjän tarvitsemia tietoja | ||||
| objektimoduulin osien pituudet | ||||
| käännös päivämäärä | ||||
| kääntäjän nimi ja versio | ||||
| ensimmäisen suoritettavan käskyn osoite | ||||
| ellei aina 0 | ||||
| EXPORT-hakemisto | |||
| tunnukset, jotka näkyvät (eli niihin voi viitata) muille moduuleille | |||
| rutiinit, aliohjelmat, (oliot, metodit) | |||
| yhteiskäyttöinen data | |||
| tunnuksen osoite (= symbolin arvo) | |||
| mahdollinen käyttöoikeus | |||
| R/W/E/RW | |||
| IMPORT-hakemisto | |||
| muissa moduuleissa määritellyt tunnukset, joihin viitataan tässä moduulissa | |||
| tunnus | |||
| niiden käskyjen osoitteet, jossa tunnus esiintyy | |||
| Koodi ja alustettu data | |||
| alustamattomille muuttujille ei tarvitse varata (vielä) tilaa, mutta ne on otettava huomioon data-alueen koossa | |||
| Uudelleensijoitushakemisto | |||
| niiden käskyjen osoitteet, joiden osoiteosaa on korjattava, kun siirrytään moduulien yhteiseen osoiteavaruuteen | |||
| esim. kaikki IMPORT hakemiston kautta tehdyt viittaukset? | |||
| esim. kaikki absoluuttiset muistisoitteet? | |||
| suoraviivainen lisäys (joka käskyyn) ei toimi, sillä käskyn osoiteosa voi olla vakio, jota ei saa muuttaa | |||
| erikseen (a) paikalliseen dataan
viittaavat ja (b) hyppykäskyt, sillä linkittäessä yhdistetään erikseen data- ja koodialueet |
|||
Korkean tason kielen käännös (2)
| Enemmän vaiheita | |||
| Syntaktisten alkioiden etsintä | |||
| Syntaksipuun generointi ja jäsennys | |||
| Lauseiden tunnistaminen syntaksipuun avulla | |||
| Välikielen (välikoodin) generointi (ei aina) | |||
| Koodin generointi | |||
| ei (yleensä) Java-ohjelmille | |||
| Uudelleensijoitusongelma | |||
| jokaisen objektimoduulin osoitteet alkavat 0:sta | |||
| tulosmoduulissa kaikki yhdessä lineaarisessa osoiteavaruudessa | |||
| useimpien moduulien kaikkia osoitteita täytyy muuttaa | |||
| käskyjen osoitteet | |||
| datan osoitteet | |||
| Neljä moduulia: A, B, C ja D | |
| Laske joka moduulille uudelleen- sijoitusvakio (moduulin alkuosoite) |
|
| Lisää k.o. vakio kunkin moduulin sisäisiin viitteisiin | |
| Etsi kaikki moduulien väliset viitteet, ja aseta kyseisten viitteiden osoitteet oikein |
|
Muuttujan X
viittausten päivitys (3)
| Miten löytää linkityksen aikana kaikki (moduulin) kohdat, jossa muuttujaan X viitataan? | ||
| Vastaus 1: taulukko, jossa kaikki kohdat listattu | ||
| taulukko voi olla hyvin iso | ||
| kaikille muuttujille tilaa maksimitarpeen verran? | ||
| Vastaus 2: Muuttujan X viittaukset on linkitetty keskenään linkitetyksi listaksi objektimoduulissa | ||
| vain linkitetyn listan alkuosoite
taulukossa (tarvitaan vain yksi osoite per muuttuja) |
||
| X:n osoitteen paikalla aluksi linkki seuraavaan käskyyn, missä X:ään viitataan | ||
| listan voi käyttää vain yhden kerran? | ||
Muuttujan X viittaukset linkitettynä listana (1)
| Tavallinen (staattinen) linkitys vaatii, että kaikki ohjelmakoodissa viitatut moduulit ja kirjastorutiinit on linkitetty ennen suoritusta | |||
| Ajomoduulista tulee hyvin iso | |||
| mukana myös paljon moduuleja, joihin ei yhdellä suorituskerralla tule lainkaan viittauksia | |||
| esim: kääntäjässä koodin optimointikoodi, vaikka koodin optimointia ei suoriteta joka kerta | |||
| esim: pelissä tasojen 8-22 moduulit, kun aloittelija ei pääse tasoa 3 ylemmäksi vielä kuukausiin | |||
| Jätetään linkityksessä kutsukohdat muihin moduuleihin auki | ||
| Pienempi ajomoduuli, mutta hitaampi suorittaa | ||
| Viittaus ”ratkaisemattomaan” (eli ei-linkitettyyn) moduuliin ratkotaan suoritusaikana |
||
| suoritus keskeytyy ja puuttuva moduuli linkitetään paikalleen (kaikki viittaukset siihen korjataan kuntoon) | ||
| DLL - Dynamically Linked Library | ||
| koodia, dataa tai molempia | ||
| Säästää tilaa myös yhteiskäytön vuoksi |
||
| Helpompi korjata virheitä | ||
| ei tarvita uutta käännöstä eikä lähdekielistä koodia! | ||
| riittää kun DLL vaihdetaan uuteen | ||
| seuraavassa suorituksessa uusi versio käyttöön | ||
| Ajomoduuli kootaan kuten tavallinen objektimoduuli | ||
| DLL moduulit ja DLL viittaukset merkitty erikoislipukkeella (huomioidaan linkityksen yhteydessä) | ||
Windows DLL:n linkityksen kaksi tapaa
| Epäsuora dynaaminen linkitys | |
| Suora dynaaminen linkitys | |
| DLL:ssä oleva koodi suoritetaan osana kutsuvaa prosessia käyttäen sen omaa aktivointitietuepinoa | |
DLL:n epäsuora dynaaminen linkitys
| Kaikki viitatut moduulit ladataan (lataus aloitetaan) virtuaalimuistiin ja niihin viitataan staattisesti linkitetyn pienemmän liitospalikan (import library) avulla |
DLL:n suora dynaaminen linkitys
| Koodiin generoidaan suoraan viitepaikalle käskyt, joiden avulla linkitys tapahtuu tarvittaessa | ||
| DLL ladataan vain jos siihen tulee viittaus |
||
| hidas, koska lataaminen alkaa vasta ensimmäisen viittauksen yhteydessä |
||
| Milloin symbolin L suoritusaikainen muistiosoite tai muu lopullinen arvo sidotaan (lasketaan valmiiksi)? | ||
| ohjelman kirjoitusaikana? | ||
| käännösaikana? | ||
| linkityksessä? | ||
| latauksessa? | ||
| kantarekisterin asetuksen aikana? | ||
| osoitteen sisältämän konekäskyn suoritusaikana? | ||
| Jos muuttujan sijaintipaikkaa siirretään sitomisen jälkeen, mennään metsään … | ||
Sijainnista riippumaton koodi (3)
| Jos koodi siirretään toiseen paikkaan, niin mitään osoitetta ei tarvitse päivittää | ||
| Kaikki muistiviittaukset ovat | ||
| absoluuttisia (esim. keskeytys käsittelijän osoite), | ||
| suhteessa PC:hen, tai | ||
| pinossa | ||
| Siellä ei ole viittauksia mihinkään koodiin tai tietorakenteeseen suorien (fyysisten) muistiosoitteiden avulla (tähän koodisegmenttiin) | ||
| Ajomoduulista luodaan suorituskelpoinen
prosessi (rakennetaan PCB ja sen viitteet kuntoon) |
||
| Prosessin koodialueet (tai ainakin sen pääohjelma) ja tarvittava data-alue ladataan muistiin, prosessi siirretään ready (Ready-to-Run) jonoon | ||
| Sitten kun prosessi saa suoritusvuoron suorittimella, MMU ja laiterekisterit ladataan PCB:n avulla tämän prosessin tiedoilla | ||
| virtuaalimuistia käytettäessä joidenkin nimien sidonta tehdään viime hetkellä (konekäskyn suoritusaikana) MMU:n avulla | ||