Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
CMa | lihtsustatud C
abstraktne masin
CMa arhitektuur
Avaldiste transleerimine
Lausete transleerimine
Staatiline ja dunaamiline maluhaldus
Funktsioonide transleerimine
Kogu programmi transleerimine
CMa arhitektuur
Iga abstraktne masin maarab mingi hulga kaske, mis ontaitmiseks abstraktsel riistvaral.
Seda abstraktset riistvara v~oib vaadelda kui teatavate and-mestruktuuride kogumit, mida kasud kasutavad
. . . ja mida juhib taitmisaegne susteem (run-time system).
2 / 66
CMa arhitektuur
Magasin:
SP
10
S
S = Stack | malupiirkond andmete hoidmiseks, kus uuteelementide lisamine/eemaldamine kaib LIFO printsiibil.
SP = Stack-Pointer | register, mis sisaldab ulemise(so. viimasena lisatud) elemendi aadressit.
Lihtsustus: k~oik mittestruktuurset tuupi vaartused on samasuurusega ja mahuvad uhte magasini pessa.
3 / 66
CMa arhitektuur
Kood:
PC
10
C
C = Code-store | malupiirkond programmikoodi hoidmiseks;igas pesas on tapselt uks abstraktse masina kask.
PC = Program Counter | register, mis sisaldab jargmisenataidetava kasu aadressit.
Algselt sisaldab PC aadressit 0; so. C[0] sisaldab k~oigeesimesena taidetavat kasku.
4 / 66
CMa arhitektuur
Programmi taitmine:
Masin laadib kasu C[PC] registrisse IR (Instruction-Register),seejarel suurendab registrit PC uhe v~orra ning l~opuks taidabselle kasu:
while (true) {IR = C[PC]; PC++;
execute (IR);
}Kasu taitmine v~oib muuta registri PC sisu (hupped).
Masina peatsukli katkestab kask halt, mis tagastab kontrollivaliskeskkonnale.
Ulejaanud kasud toome sisse jark-jargult vastavalt vajadu-sele.
5 / 66
Lihtsad avaldised ja omistamine
Ulesanne: vaartustada avaldis (6 + 2) � 4� 1; s.t. genereeridakaskude jada, mis
leiab avaldise vaartuse ja
lisab selle magasini tippu.
Idee:
k~oigepealt arvutame alamavaldiste vaartused,
salvestame need magasini tippu ning
seejarel rakendame antud operaatorile vastavat kasku.
6 / 66
Lihtsad avaldised ja omistamine
Uldprintsiibid:
kasud eeldavad, et nende argumendid on ulemistes pesades,
kasu taitmine tarvitab oma argumendid ara,
tulemus salvestatakse magasini tippu.
loadc q
qSP++;
S[SP] = q;
Kask loadc q ei oma argumente ja salvestab konstandi q maga-sini tippu.
NB! Registri SP sisu on joonisel esitatud ainult kaudselt magasinik~orguse kaudu.
7 / 66
Lihtsad avaldised ja omistamine
mul
217
3
SP--;
S[SP] = S[SP] � S[SP+1];
Kask mul eeldab magasinis kahte argumenti, tarvitab need ara jasalvestab nende korrutise magasini tippu.
Teised binaarsetele aritmeetilistele ja loogilistele operaatoritelevastavad kasud add, sub, div, mod, and, or, xor, eq, neq, le,leq, ge ja geq tootavad analoogselt.
8 / 66
Lihtsad avaldised ja omistamine
Naide: operaator leq
leq
13
7
NB! Arv 0 esitab vaara t~oevaartust, k~oik teised taisarvud ont~oesed vaartused.
9 / 66
Lihtsad avaldised ja omistamine
Unaarsed operaatorid neg ja not tarvitavad uhe argumendi japrodutseerivad uhe tulemuse:
neg
-77
S[SP] = -S[SP];
not
03 if (S[SP] 6= 0)S[SP] = 0;
else
S[SP] = 1;
10 / 66
Lihtsad avaldised ja omistamine
Naide: avaldisele 1 + 7 vastab kaskude jada:
loadc 1
loadc 7
add
Selle koodi taitmine annab:
loadc 1 loadc 7 add
1 1
7
8
11 / 66
Lihtsad avaldised ja omistamine
Muutujatele vastavad magasini S pesad:
x:
y:
Koodi genereerimist kirjeldavad funktsioonid code, codeLja codeR.
Argumendid: transleeritav suntaktiline konstruktsioon jaaadresskeskkond (so. funktsioon, mis igale muutujale seabvastavusse tema suhtaadressi magasinis).
12 / 66
Lihtsad avaldised ja omistamine
Muutujaid kasutatakse kahel erineval moel.
Naiteks omistuslauses x = y + 1 oleme huvitatud muutujay vaartusest, kuid muutuja x aadressist.
Muutuja suntaktiline asukoht maarab, kas me vajame temaL-vaartust v~oi R-vaartust
muutuja L-vaartus = tema aadressmuutuja R-vaartus = tema vaartus
Funktsioon codeL e � emiteerib keskkonnas � avaldise e L-vaartust arvutava koodi.
Funktsioon codeR e � teeb sama R-vaartuse jaoks.
NB! Mitte igal avaldisel pole L-vaartust (nait.: x+ 1).
13 / 66
Lihtsad avaldised ja omistamine
Binaarsete operaatorite transleerimine:
codeR (e1 + e2) � = codeR e1 �codeR e2 �add
{ Analoogselt teiste binaaroperaatorite korral.
Unaarsete operaatorite transleerimine:
codeR (�e) � = codeR e �neg
{ Analoogselt teiste unaaroperaatorite korral.
Baasvaartuste transleerimine:
codeR q � = loadc q
14 / 66
Lihtsad avaldised ja omistamine
Kask load salvestab magasini tippu selle magasini pesa sisu,mille aadress on ulemises pesas:
load
7 7
7
S[SP] = S[S[SP]];
15 / 66
Lihtsad avaldised ja omistamine
Kask store kirjutab ulalt teise pesa sisu pessa, kuhu viitab uleminepesa ja jatab kirjutatud vaartuse ka magasini tippu:
store
7
77
S[S[SP]] = S[SP-1];
SP--;
16 / 66
Lihtsad avaldised ja omistamine
Muutujate transleerimine:
codeL x � = loadc (� x)codeR x � = codeL x �
load
Omistusavaldise transleerimine:
codeR (x = e) � = codeR e �codeL x �store
17 / 66
Lihtsad avaldised ja omistamine
Naide: olgu e � (x = y � 1) and � = fx 7! 4; y 7! 7g,siis codeR e � emiteerib koodi:
loadc 7
load
loadc 1
sub
loadc 4
store
Taiustusi: sagedasti esinevate kasukombinatsioonide jaoks v~oibsisse tuua uusi kaske, naiteks:
loada q = loadc qload
storea q = loadc qstore
18 / 66
Laused ja lausete jadad
Kui e on avaldis, siis e; on lause.
Lausel ei ole argumente, ega vaartust.
Seega registri SP sisu peab enne ja parast lausele vastavakoodi taitmist olema sama.
code (e; ) � = codeR e �pop
code (s ss) � = code s �code ss �
code " � = // tuhi kaskude jada
Kask pop eemaldab magasinist k~oige ulemise peas:
pop
7
SP--;
19 / 66
Tingimuslaused ja tsuklid
Lihtsuse parast kasutame hupete sihtkohana sumbolmargen-deid, mis hiljem asendatakse absoluutaadressitega.
Absoluutaadressite asemel v~oib kasutada ka suhtaadresseid;so. relatiivseid registri PC tegeliku vaartuse suhtes.
Viimase lahenemise eeliseks on:
{ suhtaadressid on reeglina vaiksemad;{ kood on ringit~ostetav (relocatable).
20 / 66
Tingimuslaused ja tsuklid
Kask jump A teostab huppe aadressile A; magasini ei muudeta:
jump A
PC PC A
PC = A;
21 / 66
Tingimuslaused ja tsuklid
Kask jumpz A teostab tingimusliku huppe; kui magasini tipusolev argument on 0, siis toimub hupe aadressile A; vastaselkorral hupet ei toimu:
jumpz A
PC PC
jumpz A
PCPC
0A
3
if (S[SP] = 0)PC = A;
SP--;
22 / 66
Tingimuslaused ja tsuklid
Uheharulise tingimuslause s � if (e) s1 transleerimine:
genereerime koodi tingimuse e ja lause s1 jaoks;
lisame tingimusliku huppekasu nende vahele.
code (if (e) s1) � =codeR e �jumpz A
code s1 �A: . . .
jumpz
codeR for e
code for s1
23 / 66
Tingimuslaused ja tsuklid
Kaheharulise tingimuslause s � if (e) s1 else s2transleerimine:
code (if (e) s1 else s2) � =codeR e �jumpz A
code s1 �jump B
A: code s2 �B: . . .
jumpz
jump
codeR for e
code for s1
code for s2
24 / 66
Tingimuslaused ja tsuklid
Naide: olgu � = fx 7! 4; y 7! 7g ja
s � if (x > y) (i)x = x� y; (ii)
else y = y � x; (iii)
siis code s � emiteerib koodi:
loada 4
loada 7
ge
jumpz A
(i)
loada 4
loada 7
sub
storea 4
pop
jump B
(ii)
A: loada 7loada 4
sub
storea 7
pop
B: . . .(iii)
25 / 66
Tingimuslaused ja tsuklid
while-tsukli s � while (e) s1 transleerimine:
code (while (e) s1) � =A: codeR e �jumpz B
code s1 �jump A
B: . . .
jumpz
jump
codeR for e
code for s1
26 / 66
Tingimuslaused ja tsuklid
Naide: olgu � = fa 7! 7; b 7! 8; c 7! 9g ja
s � while (a > 0) f (i)c = c+ 1; (ii)a = a� b; (iii)
gsiis code s � emiteerib koodi:
A: loada 7loadc 0
ge
jumpz B
(i)
loada 9
loadc 1
add
storea 9
pop
(ii)
loada 7
loada 8
sub
storea 7
pop
(iii)
jump A
B: . . .
27 / 66
Tingimuslaused ja tsuklid
for-tsukkel s � for (e1; e2; e3) s1 on ekvivalentne while-tsukliga e1; while (e2) fs1 e3; g (eeldusel, et s1 ei sisaldacontinue-lauset)
code (for (e1; e2; e3) s1) � = codeR e1 �pop
A: codeR e2 �jumpz B
code s1 �codeR e3 �pop
jump A
B: . . .
28 / 66
Massiivid, kirjed ning staatiline maluhaldus
Eesmark: staatiliselt (so. kompileerimisajal) siduda iga muu-tujaga x �kseeritud (relatiivne) aadress � x.
Eeldame, et baastuupi muutujad (nait. int, . . . ) mahuvad
uhte malupessa.
Seome muutujatega aadressid nende deklareerimise jarjekorrasalustades aadressist 1.
Seega, deklaratsioonide d � t1 x1; : : : tk xk; (ti on baastuup)korral saame aadresskeskkonna � sellise, et
� xi = i; i = 1; : : : ; k
29 / 66
Massiivid, kirjed ning staatiline maluhaldus
Massiiv on staatiliselt maaratud suurusega jarjestikustemalupesade hulk.
Ligipaas kasutades taisarvulisi indekseid, mis algavadnullist.
Massiivi aadress on tema esimese elemendi a[0] aadress.
Naide: deklaratsioon int[11]a; de�neerib 11 elemendilisemassiivi.
a[10]
a[1]
a[0]
30 / 66
Massiivid, kirjed ning staatiline maluhaldus
De�neerime funktsiooni sizeof (tahistus j � j), mis leiabtuubi maluvajadused:
jtj =
(1 if t is a primitive typek � jt0j if t � t0[k]
Seega, deklaratsioonide d � t1 x1; : : : tk xk; korral
� x1 = 1� xi = � xi�1 + jti�1j i > 1
Kuna j � j saab arvutada kompileerimise ajal, siis saab kaaadresskeskkonna � arvutada kompileerimise ajal.
31 / 66
Massiivid, kirjed ning staatiline maluhaldus
Olgu t a[c]; massiivi deklaratsioon.
Siis i-nda komponendi algaadress on � a+ jtj � (rval of i)
codeL (a[e]) � = loadc (� a)codeR e �loadc jtjmul
add
32 / 66
Massiivid, kirjed ning staatiline maluhaldus
Uldjuhul v~oib massiiv olla esitatud avaldisena, mis tulebenne indekseerimist vaartustada.
C-s on deklareeritud massiiv viitkonstant, mille R-vaartuson massiivi algaadress.
codeL (e1[e2]) � = codeR e1 �codeR e2 �loadc jtjmul
add
codeR e � = codeL e � e is an array
33 / 66
Massiivid, kirjed ning staatiline maluhaldus
Kirje on nime omavate, v~oimalik et erinevat tuupi,komponentide hulk.
Ligipaas komponentidele nimede (selektorite) abil.
Lihtsustusena eeldame, et kirjekomponentide nimesid eikasutata mujal.
{ Alternatiiv: hallata iga kirjetuubi st jaoks eraldikeskkonda �st.
Kuulugu struct f int a; int b; g x; deklaratsioonidehulka:
{ kirje x suhtaadress on tema esimese pesa aadress;{ komponentide aadressid on relatiivsed kirje algaadressisuhtes; so. ulaltoodud naites a 7! 0; b 7! 1.
34 / 66
Massiivid, kirjed ning staatiline maluhaldus
Olgu t � struct f t1 c1; : : : tk ck; g, siis
jtj =Pk
i=1 jtij� c1 = 0� ci = � ci�1 + jti�1j i > 1
Seega komponendi x:ci aadress on � x+ � ci
codeL (e:c) � = codeL e �loadc (� c)add
35 / 66
Viidad ja dunaamiline maluhaldus
Kuhi:
NP
EP
SP
0
SMAX
H
H = Heap | malupiirkond dunaamilise elueaga andmetele.NP = New-Pointer | register, mis sisaldab kuhja k~oige
alumise taidetud pesa aadressit.EP = Extreme-Pointer | register, mis sisaldab k~oige ulemise
pesa aadressi, kuhu SP v~oib antud funktsiooni taitmiselviidata.
36 / 66
Viidad ja dunaamiline maluhaldus
Magasin ja kuhi kasvavad uksteise suunas, aga ei tohikattuda (stack overow).
"Kokkup~orge" v~oib olla p~ohjustatud nii SP suurendamisestkui NP vahendamisest.
EP aitab valtida uletaitumist magasini operatsioonidekorral.
EP vaartuse saab maarata staatiliselt.
Kuhjast malu v~ottes tuleb uletaitumist kontrollida.
37 / 66
Viidad ja dunaamiline maluhaldus
Viidad v~oimaldavad ligipaasu anonuumsetele,dunaamiliselt loodud, objektidele, mille eluiga ei allu LIFOprintsiibile.
Viitvaartuste saamiseks on kaks v~oimalust:
{ funktsiooni malloc(e) valjakutse reserveeribmalupiirkonna mille suurus on e vaartus ning valjastabselle piirkonna algusaadressi;
{ aadressoperaatori & rakendamine muutujale valjastabselle muutuja aadressi (so. L-vaartuse).
codeR (malloc(e)) � = codeR e �new
codeR (&e) � = codeL e �
38 / 66
Viidad ja dunaamiline maluhaldus
NP
new
NP
n
n
if (NP - S[SP] � EP)S[SP] = NULL;
else {NP = NP - S[SP];
S[SP] = NP;
}
NULL on spetsiaalne viitkonstant; samastatakse taisarvulisekonstandiga 0.Uletaitumise korral valjastatakse NULL-viit.
39 / 66
Viidad ja dunaamiline maluhaldus
Viidatava vaartuste saamiseks on kaks v~oimalust:
{ operaatori � rakendamine avaldisele e valjastab malupesasisu, mille aadress on avaldise e R-vaartus;
{ kirje komponendi selekteerimine labi viida e!c onekvivalentne avaldisega (�e):c.
codeL (�e) � = codeR e �codeL (e!c) � = codeR e �
loadc (� c)add
40 / 66
Viidad ja dunaamiline maluhaldus
Naide: olgu antud deklaratsioonid:
struct t f int a[7]; struct t � b; g;int i; j;struct t � pt;
Siis � = f a 7! 0; b 7! 7; i 7! 1; j 7! 2; pt 7! 3 g.
Avaldise ((pt!b)!a)[i+ 1] korral emiteeritakse kood:
loada 3
loadc 7
add
load
loadc 0
add
loada 1
loadc 1
add
loadc 1
mul
add
41 / 66
Viidad ja dunaamiline maluhaldus
Malu vabastatakse C-s funktsiooni free(e) valjakutse abil.
Antud malupiirkond margistatakse kui vaba ja pannaksespetsiaalsesse vabamalu listi (free list), kust malloc saabvajadusel selle uuesti kasutusele v~otta.
Probleemid:
{ peale malupiirkonna vabastamist v~oivad m~oned, ikkaveel kattesaadavad, viidad sellele viidata (danglingreferences);
{ malu v~oib ajapikku muutuda fragmenteerituks;
free memory fragments
{ vabamalu listi haldamine v~oib olla kulukas.
42 / 66
Viidad ja dunaamiline maluhaldus
Alternatiiv: funktsiooni free valjakutse korral ei tehtamidagi.
code (free(e); ) � = codeR e �pop
Malu taitumisel vabastatakse kindlasti mitte-kattesaadavmalu automaatselt kasutades prugikoristust (garbagecollection).
+ Malu v~otmine ja "vabastamine" on lihtne ja vagaefektiivne.
+ Pole "ripnevate viitade" probleemi.+ Mitmed prugikoristuse algoritmid defragmenteerivad
kasutusel oleva malu.� Prugikoristus v~oib olla aegan~oudev, mist~ottu v~oivad
tekkida programmi taitmises margatavad pausid.
43 / 66
Funktsioonid
Funktsiooni de�nitsioon koosneb neljast komponendist:
{ funktsiooni nimi, mille kaudu toimub temavaljakutsumine;
{ funktsiooni formaalsete parameetrite spetsi�katsioon;{ funktsiooni resultaadi tuup;{ funktsiooni keha.
C-s kehtib:
codeR f � = f = starting address of f code
Seega peab aadresskeskkond haldama ka funktsioonidenimesid!
44 / 66
Funktsioonid
Naide:
int fac (int x) fif (x � 0) return 1;else return x � fac(x� 1);
g
main () fint n;n = fac(2) + fac(1);printf("%d"; n);
g
Samast funktsioonist v~oib olla mitu aktiivset eksemplari.
main
fac printffac
facfac
fac
45 / 66
Funktsioonid
Funktsiooni iga eksemplari formaalsed parameetrid ja lo-kaalsed muutujad tuleb hoida eraldi.
Selleks reserveerime funktsioonide iga valjakutse korral ma-gasinis spetsiaalse malupiirkonna, freimi (Stack Frame).
FP (Frame Pointer) on register, mis viitab aktiivse frei-mi viimasele organisatoorsele pesale ja mida kasutatakseformaalsete parameetrite ja lokaalsete muutujate adresseeri-miseks.
46 / 66
Funktsioonid
Freimi struktuur:
FP
SP
formal parameters
organizational cells
return value
local variables
PCold
FPold
EPold
47 / 66
Funktsioonid
Valjakutsuja peab peale valjakutsutud funktsiooni l~opetamistolema v~oimeline jatkama taitmist omas freimis.
Seet~ottu tuleb funktsiooni valjakutsel salvestada:
{ valjakutsuja freimi aadress FP;{ koodi aadress, kust tuleb jatkata peale valjakutsel~opetamist (so. kasuregister PC);
{ valjakutsuja magasini maksimaalne v~oimalik aadress EP.
Lihtsustus: eeldame, et funktsioonide resultaatvaartused ma-huvad uhte malupessa.
48 / 66
Funktsioonid
Peame eristama kahte eri liiki muutujaid:
{ globaalsed muutujad, mis on de�neeritudfunktsioonidest valjaspool;
{ lokaalsed (ehk automaatsed) muuutujad (k.a. formaalsedparameetrid), mis on de�neeritud funktsioonide siseselt.
Aadresskeskkond � seob muutujanimedega paarid
(tag ; a) 2 fG;Lg � N
NB! Paljud keeled lubavad muutujate nahtavustkitsendada mingi ploki piiresse.
Erinevate programmiosade transleerimine kasutab reeglinaerinevaid aadresskeskkondi.
49 / 66
Funktsioonid
0 int i;struct list fint info;struct list �next ;
g �l;
2 main () fint k;scanf("%d";&i);scanlist(&l);printf("%d"; ith(l; i));
g
1 int ith (struct list �x; int i) fif (i � 1) return x!info;else return ith(x!next ; i�1);
g
50 / 66
Funktsioonid
0 int i;struct list fint info;struct list �next ;
g �l;
2 main () fint k;scanf("%d";&i);scanlist(&l);printf("%d"; ith(l; i));
g
1 int ith (struct list �x; int i) fif (i � 1) return x!info;else return ith(x!next ; i�1);
g
0 global env.�0 i 7! (G; 1)
l 7! (G; 2)ith 7! (G; ith)
main 7! (G; main)
50 / 66
Funktsioonid
0 int i;struct list fint info;struct list �next ;
g �l;
2 main () fint k;scanf("%d";&i);scanlist(&l);printf("%d"; ith(l; i));
g
1 int ith (struct list �x; int i) fif (i � 1) return x!info;else return ith(x!next ; i�1);
g
1 env. for function ith�1 x 7! (L; 1)
i 7! (L; 2)l 7! (G; 2)
ith 7! (G; ith)main 7! (G; main)
50 / 66
Funktsioonid
0 int i;struct list fint info;struct list �next ;
g �l;
2 main () fint k;scanf("%d";&i);scanlist(&l);printf("%d"; ith(l; i));
g
1 int ith (struct list �x; int i) fif (i � 1) return x!info;else return ith(x!next ; i�1);
g
2 env. for function main�2 k 7! (L; 1)
i 7! (G; 1)l 7! (G; 2)
ith 7! (G; ith)main 7! (G; main)
50 / 66
Funktsioonid
Olgu f funktsioon, milles kutsutakse valja funktsioon g.
Funktsiooni f nimetame kutsujaks (caller) ning funktsioonig kutsutavaks (callee).
Funktsiooni valjakutse puhul emiteeritav kood tuleb ara ja-gada kutsuja ja kutsutava vahel.
Tapne jaotus s~oltub sellest, et kes omab millist informat-siooni.
51 / 66
Funktsioonid
Tegevused valjakutsel ja kutsutavasse sisenemisel:
1 registrite FP ja EP salvestamine;
2 aktuaalsete argumentide arvutamine;
3 kutsutava koodi g algaadressi maaramine;
4 uue FP sattimine;
5 PC salvestamine ja g algusse huppamine;
6 uue EP sattimine;
7 lokaalsetele muutujatele malu eraldamine.
g mark
ocall
g enter
g alloc
Tegevused kutsutavast lahkumisel:1 registrite FP, EP ja SP taastamine;
2 tagasipoordumine f -i koodi; so. PC taastamine.
)return
52 / 66
Funktsioonid
codeR (g(e1; : : : ; en)) � = markcodeR e1 �. . .codeR en �codeR g �call n
Aktuaalsete parameetritena esinevatel avaldistel leitaksenende R-vaartused
{ parameetrite edastamine vaartuse kaudu (call-by-value).
Funktsioon g v~oib olla avaldis, mille R-vaartus onkutsutava funktsiooni algaadress.
53 / 66
Funktsioonid
Kask mark reserveerib malu organisatoorsete pesade jaresultaatvaartuse jaoks ning salvestab registrid FP ja EP:
FP FP
EP EP
mark
e
e
e
S[SP+2] = EP;
S[SP+3] = FP;
SP = SP + 4;
54 / 66
Funktsioonid
Kask call n salvestab jatkuaadressi ning omistab registriteleFP, SP ja PC uued vaartused:
FP FP
PC
call n
PCn
pq
p
q
FP = SP - n - 1;
S[FP] = PC;
PC = S[SP];
SP--;
55 / 66
Funktsioonid
Funktsiooni nimi on viitkonstant, mille R-vaartus onfunktsiooni algaadress.
Funktsiooni viida kaudu vaartuse v~otmine valjastab sellesama viida.
{ Naide: deklaratsiooni int (�)()g; korral on valjakutsedg() ja (�g)() ekvivalentsed.
Argumentidena antavad kirjed kopeeritakse.
codeR f � = loadc (� f) f on funktsiooni nimicodeR (�e) � = codeR e � e on funktsiooni viitcodeR e � = codeL e � e on kirje suurusega k
move k
56 / 66
Funktsioonid
Kask move k kopeerib k pesa magasini tippu:
move k
k
for (i=k-1; i�0; i--)S[SP+i] = S[S[SP]+i];
SP = SP + k - 1;
57 / 66
Funktsioonid
code (t f (args)fvars ssg) � = f : enter qalloc k
code (ss) �freturn
kus q = maxS + kmaxS = lokaalse magasini maksimaalne sugavusk = malu lokaalsetele muutujatele�f = f -i aadresskeskkond
58 / 66
Funktsioonid
Kask enter q seab registrile EP uue vaartuse:
enter q
q
EP
EP = SP + q;
if (EP�NP)Error ("Stack Overflow");
NB! Kui malu pole piisavalt, siis programmi too katkestatakse.
59 / 66
Funktsioonid
Kask alloc k reserveerib magasinis malu lokaalsete muutujatejaoks:
alloc k
k
SP = SP + k;
60 / 66
Funktsioonid
Kask return taastab registrite PC, FP ja EP sisu ning jatabresultaatvaartuse magasini tippu:
return
EP
FP
PCPC
FP
EP
v
e
p
e
p
v
PC = S[FP];
EP = S[FP-2];
if (EP�NP)Error ("Stack Overflow");
SP = FP - 3;
FP = S[SP+2];
61 / 66
Funktsioonid
Lokaalsetele muutujatele ja formaalsetele parameetriteleligipaas toimub relatiivselt registri FP suhtes:
codeL x � =
(loadc j if � x = (G; j)loadrc j if � x = (L; j)
Kask loadrc j arvutab FP ja j summa:
loadrc j
FPFP
f+j
ff
SP++;
S[SP] = FP + j;
62 / 66
Funktsioonid
Analoogselt kaskudega loada j ja storea j toome sisse kasudloadr j ja storer j:
loadr j = loadrc jload
storer j = loadrc jstore
return-lausele vastab vaartuse omistamine muutujale suhtaad-ressiga -3:
code (return e; ) � = codeR e �storer -3
return
63 / 66
Funktsioonid
Naide: int fac(int x) fif (x � 0) return 1;else return x � fac(x� 1);
g
Siis �fac = fx 7! (L; 1)g ja emiteeritav kood on:
fac: enter 7alloc 0
loadr 1
loadc 0
leq
jumpz A
loadc 1
storer -3
return
jump B
A: loadr 1mark
loadr 1
loadc 1
sub
loadc fac
call 1
mul
storer -3
return
B: return
64 / 66
Kogu programmi transleerimine
Abstraktse masina olek enne programmi kaivitamist:
SP = -1 FP = EP = 0 PC = 0 NP = MAX
Olgu p � vars fdef 1 : : : fdef n, kus fdef i on funktsiooni fide�nitsioon ja uks de�neeritud funktsioonidest on nimega main.
Emiteeritav kood koosneb jarmistest osadest:
funktsioonide de�nitsioonidele fdef i vastav kood;
globaalsetele muutujatele malu reserveerimine;
funktsiooni main(); valjakutse kood;
kask halt.
65 / 66
Kogu programmi transleerimine
code p ; = enter (k + 6)alloc (k + 1)mark
loadc main
call 0
pop
halt
f1 : code fdef 1 �. . .
fn : code fdef n �
kus ; = tuhi aadresskeskkond� = globaalne aadresskeskkondk = malu globaalsetele muutujatele
66 / 66
CMaCMa arhitektuurAvaldisedLausedMassiivid ja kirjedViidadFunktsioonidProgramm