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 |