Professional Documents
Culture Documents
Generisanje koda
Faza generisanja koda je praktino poslednja faza u procesu prevoenja jezika. Obino se
nadovezuje na generisanje meukoda i koristi informacije sauvane u Tabeli simbola, Sl. 12.1.
Kod nekih kompilatora se nakon generisanja koda vri njegova optimizacija mada se veoma esto
optimizacija koda vri i na nivou meukoda, o emu e biti rei u narednom poglavlju.
Osnovni zadatak generatora koda je da generie ispravan kod pri emu je bitno da taj kod bude i
to je mogue efikasniji.
Tabela simbola
Naini adresiranja
Polja soure i destination nisu dovoljna da specificiraju ceo podatak ili adresu podatka ve samo
kodiraju nain adresiranja koji je primenjen odnosno da li se u rei koja sledi iza naredbe nalazi
podatak ili adresa. U Tabeli 12.1 su navedeni naini adresiranja koji se koriste kod ovog
asemblerskog jezika kao i dodatna cena koju nain adresiranja pridodaje ceni naredbe u kojoj je
primenjen.
Tabela 12.1 Pregled zastupljenih naina adresiranja
Apsolutno adr. M M 1
registarsko R R 0
Neposredno #c 1
Apsolutno adresiranje
U ovom sluaju memorijska lokacija ije je simboliko ime navedeno u naredbi je izvorite ili
destinacija. Na primer, u naredbi:
MOV R0,M
Sadraj registra R0 se prosleuje u memorijsku lokaciju M: (R0)M.
U ovom sluaju adresa memorijske lokacije sledi neposredno iza same naredbe, pa je zato uzeto
da samo adresiranje poveava cenu za jedan.
Registarsko adresiranje
Kod registarskog adresiranja navedeni registar je izvorite ili odredite podatka na koji se odnosi
naredba. U prethodnom primeru MOV naredbe sadraj registra R0 se prebacuje u mamorijsku
lokaciju M.
Kako se registri nalaze u procesoru i adresiranju se implicitno, nije potrebno da se zauzima
memorijski prostor za pamenje njihovih adresa, ovaj nain adresiranja ne poveava cenu
naredbe u kojoj se koristi.
Indeksiranje
U ovom sluaju adresa izvorita ili odredita se formira tako to se sadraju registra koji je
naveden u zapisu naredbe dodaje vrednost konstante koja je navedena u naredbi. U ovom sluaju
vrednost konstante u binarnom odliku sledi iza same naredbe ovo adresiranje poveava cenu
naredbe za 1.
Primer:
MOV 4,(R0), M
Efekat je da se sadraj registra R0 poveava za 4, ime se formira adresa memorijske lokacije iji
se sadraj alje u memorijsku lokaciju M: (4+(R))M.
Indirektno registarsko adresiranje
Indirektno adresiranje je oznaeno sa *, i sastoji se u tome da se sadraj navedenog registra
koristi kao adresa lokacije u kojoj ili iz koje se preuzima sadraj nad kojim se izvrava navedena
operacija.
Na primer, u naredbi:MOV *R0,M efekat je ((R0))M. Sardaj memorijske lokacije ija je
adresa jednaka sadraju registra R0 se prosleije u memorijsku lokaciju M. Ovo adresiranje kao i
registarsko ne poveava cenu naredbe zato to ne zahteva dodatan memorijski prostor za
pamenje podataka o adresi.
Indirekno indeksirano adresiranje
Kada se indirektno adresiranje kombinuje sa indeksiranjem najpre se indeksiranjem formira
adresa memorijske lokacije iji se sadraj koristi kao adresa lokacije iji se sadraj koristi u
operaciji.
Na primer u naredbi *4(R0), M efekat je ((c+(R0)))M.
U ovom sluaju, kao i kod indeksiranja, konstanta koja se koristi u indeksiranju se memorie
odmah iza same naredbe tako da ovo adresiranje poveava cenu naredbe za 1.
Neposredno adresiranje
U sluaju neposrednog adresiranja podatak nad kojim se izvrava naredba je konstanta koja se
daje uz samu naredbu. Ova konstanta se memorie neposredno iza naredbe tako da takav nain
adresiranja poveava cenu naredbe za 1.
Primer:
Naredba MOV #5, R0 ima efekat 5R0, vrednost konstante 5 se upisuje u registar R0.
Cena naredbi
U mnogim sluajevima prilikom generisanja koda postoji vie mogunosti. Nekada se isti efekat
moe postii izborom razliitih instrukcija. Generator koda zbog toga prilikom generisanja koda
koristi i neku procenu cene generisanog koda koju formira na osnovu cene pojedinanih naredbi
koje mu stoje na raspolaganju. Cena naredbe u sutini zavisi od memorijskog prostora koji
zauzima sama naredba kao i do naina adresiranja koji je u njoj primenjen, o emu je bilo ve
rei. Kao to smo videli, korienje procesorskih registara ne poveava cenu naredbe dok
korienje memorijskih lokacija je poveava. Sa druge strane korienje registara procesora utie
i na efikasnost samog koda zato to se operacije mnogo bre izvravaju ututar samog procesora,
odnosno nad sadrajima koji se nalaze u registrima u odnosu na sluaj kada se sadraj preuzima
iz memorije. Zbog svega toga zadatak samog generatora koda je i efikasno korienje registara
procesora.
Razmotriemo ukupnu cenu nekih naredbi iz jezika koji koristimo kao primer:
Naredba MOV R0,R1 kojom se sadraj registra R0 kopira u registar R!, imae ukupnu
cenu 1, zato to sama naredba zauzima jednu memorijsku lokaciju i ne zahteva dodatni
memorijski prostor za pamenje adresa.
Naredba MOV R0, M , kojom se sadraj registra R0 prebacuje u memorijsku lokaciju M,
ima ukupnu cenu 2, zato to sama naredba zauzima jednu memorijsku lokaciju, a
neposredno iza nje sledi adresa memorijske lokacije koja se koristi kao odredite
sadraja.
Naredba #5,R0, kojom se u registar R0 upisuje vrednost konstante 5, ima ukupnu cenu 2,
zato to sama naredba zauzima jednu memorijsku lokaciju, a neposredno iza nje se
memorie konstanta 5.
Naredba MOV 4(R0), *12(R1) iji je efekat (4+R0)(12+(R1)). Odnosno, sadraj
memorijske lokacije ija je adresa odreena zbirok indeksa 4 i sadrajem registra R0 se
upisuje u memorijsku lokaciju ija je adresa odreena sadrajem memorijske lokacije ija
je adresa zbir konstante 12 i sadraja registra R1. Ova naredba ima ukupnu cenu 3, zato
to se jedna memorijska lokacija koristi za samu naredbu i po jedna za memorisanje
konstanti 4 i 12.
Na primeru jednostavne troadresne naredbe a := b + c pokazaemo ta sve moe i treba da bude
uzeto u razmatranje u okviru generatora koda. Ova naredba moe da bude realizovana na mnogo
razliitih naina od kojih su neki:
1. MOV b,R=
ADD c, R=
MOV RO, a ukupna cena 6, zato to svaka od naredbi ima cenu 2.
2. MOV b,a
ADD c,a ukupna cena 6, zato to svaka naredba ima cenu 3.
Ako se adrese 1, b i c nalaze u registrima R1, R2 i R3 sekvenca naredbi bi bila:
3. MOV *R1, *R0
ADD *R, R0 ukupna cena 2, zato to je cena svake naredbe 1.
Ako pretpostavimo da se vrednosti a i b nalaze u registrima R0 i R1 i da nam vrednost b ne treba
posle operacije onda je mogua i sledea sekvenca naredbi:
4. ADD R2, R1
MOV R1, a sa ukupnom cenom 3, gde je cena prve naredbe 1, a druge 2.
Iz ovog trivijalnog primera se vidi da generator koda ima dosta komplikovan zadatak ako se kao
cilj postavi genrisanje optimalnog koda. Zbog toga se obino ovom problemu pristupa tako to se
kao primarni cilj generatora postavlja generisanje funkcionalno ispravnog koda, a optimizacija
koda se vri naknadno.
12.2 Realizacija generatora koda
Pre nego definiemo sam generator koda uveemo ogranienje da se rezultat izvravanja
neke operacije zadrava u registru sve dok je potreban. Iz registra emo ga prebacivati u
memorijsku lokaciju samo u sluaju kad je taj registar potreban za neku drugu operaciju kao i
neposredno pre poziva potprograma, pre naredbe skoka kao i pre naredbe sa labelom.
Algoritam generatora koda
Generator koda preuzima naredbe iz ulazne sekvence koja predstavlja troadresni meukod. U
okviru ovih sekvenci se obino identifikuju delovi (blokovi) koji sami za sebe predstavljaju
celine, tako da se moe uitavati blok po blok. Takoe za svaki od raspoloivih registara
koristimo Descriptor registra koji ukazuje na to vrednost koje promenljive je memorisana u
registru. Takoe za svaku od promenljivih imamo Deskriptor adrese koji ukazuje na to gde je
memorisana vrednost te promenljive.
U Tabeli 12.3 su razmatrani sluajevi naredbi: a := b[i] i a[i] := b, a uzeta su obzir tri sluaja: kada
je indeks zapamen u registru procesora, u memorijskoj lokaciji ili se uva na steku.
Kod koji se generie u sluaju naredbi u kojima se koriste pokazivai prikazan je u Tabeli 12.4. I
ovde su uzeta u obzir dva oblika meunaredbi: a := *p i *p := a. Takoe su razmatrane sluajevi
kada se vrednost pokazivaa nalazi u registru procesora, u memorijskoj lokaciji ili na steku.
Tabela 12.4 Generisani kod za naredbe sa pokazivaima
Uslovne naredbe
Uslovne naredbe troadresnog koda oblika if x relop y go to z mogu da budu transformisane u
asemblerski u principu na dva naina.
Jedan nain je da se najpre x oduzme od y i da se rezultat zapamti u registru R, nakon ega se
generie naredba skoka na z ako je vrednost registra R negativna.
Drugi nain se primenjuje kod asemblerskih jezika koji koriste skup bitova (conditional code)
kojima se registruje kakva je vrednost koja je upisana u registar bilo da je ona dobijena kao
rezultat izvravanja neke operacije ili prilikom upisa vrednosti u registar. Ovi jezici obino sadre
naredbe skoka koje se vezuju za te bitove i omoguavaju prenos upravljanja na neku naredbu ako
je neki od uslova ispunje. U ovom sluaju naredba meukoda oblika if x < y go to z e biti
preslikana u sledeu sekvencu naredbi:
CMP x, y
CJ< z
Najpre se poredi vrednost podataka x i y, nakon ega se postavljaju vrednosti bitova kojima se
registruje sadraj rezultata. Druga naredba je skok na labelu z ako je u bitu kojim se registruje
uslov< upisana vrednost 1.
12.3 Organizacija memorije
Ako zamislimo da operativni sitem dodeljuje neki deo memorije kompilatoru za smetaj
programa koji se prevodi onda kompilator obino pravi raspodelu memorije tako da jedan
segment koristi za smetaj koda programa, u drugi smeta statike podatke, jedan deo memorije
se organizuje u vidu steka i slui za smetaj aktivacionih slogova potprograma (o emu e biti
rei kasnije) a deo memorije (Heap) se koristi za smetaj dinamikih podataka, Slika 12.2:
Kod programa
Statiki podaci
Stek
Heap-Dinamiki podaci
Veliina generisanog koda je poznata u toku prevoenja programa, a takoe moe da se izrauna i
memorijski proctor potreban za smetaj statikih podataka. Ove informacije kompilator moe da
iskoristi i da kod i podatke smesti u memorijske lokacije odreene apsolutnim ili relativnim
adresama.
Kod nekih jezika, kao ro je na primer FORTRAN, svi podaci se smetaju statiki. Meutim
postoje jezici kod kojih se koriste dinamiki podaci za koje se vri alokacija memorije u toku
izvravanja programa. Ovim podavima namenjen je dinamiki deo memorije. Takoe kod
programskih jezika kod kojih su dozvoljeni rekurzivni pozivi potprograma za smetaj
aktivacionih slogova potprograma koristi se stek.
Veliina steka i dinamikog dela memorije moe da se menja u toku izvravanja programa.
Prilikom implementacije nekih jezika (Pascal, C) dozvoljava se da se ovi delovi menjaju jedan na
raun drugog.
Obino se u posebnom registru procesora uva adresa vrha steka, to je takozvani pokaziva vrha
steka.
Alokacioni slogovi
Za svaki poziv potprograma kompilator obino generie jedan aktivacioni slog u kome uva sve
informacije potrebne tom pozivu potprograma. U optem sluaju aktivacioni slog ima strukturu
prikazanu na Slici 12.3. Meutim, struktura aktivacionog sloga nije ista kod svih jezika niti kod
svih kompilatora za jedan jezik. Ona se obino prilagoava potrebama kompilatora.
Namena polja u aktivacionom slogu je sledea:
1. Na vrhu sloga, smeta se vrednost koju potprogram vraa glavnom programu. Ova
vrednost se zbog efikasnosti vraa u neki od registra procesora.
2. Polje namenjeno stvarnim parametrima se koristi od strane glavnog programa da prenese
parametre potprogramu koji odgovaraju konkretnom pozivu potprograma.
3. Opciono polje sa upravljakim linkovima se koristi da se obezbedi veza sa aktivacionim
slogom modula iz kojeg je pozvan potprogram.
4. Opciono polje sa linkovima za pristup podacima postoji kod jezika koji dozvoljavaju da
se koriste nelokalni podaci, podaci iz aktivacionih slogova drugih potprograma. Ovo
polje kod Fortrana nije potrebno zato to se svi nelokalni podaci uvaju na jednom mestu.
5. Deo aktivacionog sloga namenjen uvanju statusa procesora slui da se u njemu
memoriu vrednosti registara pocesora koje su zateene u trenutku poziva potprograma.
Ovde se obino smeta vrednost Brojaa neredbi i registara procesora opte namene.
6. Polje namenjenu lokalnim podacima slui za smetaj podataka koji pripadaju samo
potprogram, definisani su u potprogramu.
7. Polje namenjeno privremenim podacima slui za memorisanje podataka koje generie
kompilator kao pomone lokacije u koje smeta meurezultate.
Veliina svih polja u aktivacionom slogu moe da se odredi u fazi prevoenja programa. Izuzetak
su samo jezici kod kojih je dozvoljeno da se dimenzije polja definiu u fazi izvravanja tako to
se ti podaci uitavaju.
Stvarni parametri
Lokalni podaci
Privremene promenljive
Primer 12.3
Uzmimo kao primer kod program CONSUME i potprograma PRODUCE, napisanih u
programskom jeziku FORTRAN
PROGRAM CONSUME
CHARACTER * 50 BAF
INTEGER NEXT
CHARACTER C, PRODUCE
DATA NEXT /1/, BUF / /
6 C = PRODUCE ( )
BUF(NEXT:NEXT) = C
NEXT = NEXT + 1
IF (C .NE. ) GO TO 6
WRITE (*, (A)) BUF
END
Kako su veliina memorijskog prostora potrebnog za smetaj koda programa i potprograma, kao i
aktivacionih slogova za ova dva modula poznati u fazi kompiliranja programa raspodela
memorije u ovom sluaju e biti kako je to prikazano na Slici 12.5.
Kod za CONSUME
Kod za PRODUCE
CHARACTER * 50 BUF
INTEGER NEXT
CHARACTER C
CHARACTER * 80 BUFFER
INTEGER NEXT
Svaki vor u aktivacionom stablu sa Slike 12.5 prestavlja jedan poziv potprograma. Pozivi
potprograma koji se izvre iz jedne instance potprograma predstavljeni su vorovima do kojih
vode potezi iz vora koji odgovara toj istanci. Pri tome redosled poziva odgovara redosledu
vorova poslatrano sleva u desno.
Na Slici 12.6 je prikazan redosled ubacivanja aktivacionih slogova u stek koji odgovara delu
aktivacionog stabla prikazanog na Slici 12.5
AKTIVACIONO STABLO Aktivacioni slogovi u steku Komentar
S
A : array
r
readarray
i : integer
q(1,3)
i : integer
p(1,3)
p(1,3)
i : integer
Slika 12.6 Dinamika ubacivana aktivacionih slogova u stek za program iz Primera 12.3.
Dinamika alokacija
Aktivacioni slogovi se smetaju u dinamiku memoriju i ne izbacuju se kao kod stek alokacije,
Slika 12.7. Delu aktivacionog stabla prikazanog na slici odgovara struktura slogva data na istoj
slici.
U sluaju statike alokacije u taki poziva potprograma kompilator treba da zapamti adresu
povratka iz potprograma i skok na sekvencu naredbi potprograma. U te svrhe generie sledeu
sekvencu:
MOV #here + 20, pp.aktivacioni_slog
GOTO pp.kod
Praktino, naredbom MOV #here + 20, pp.aktivacioni_slog, u prvu lokaciju aktivacionog sloga
pozvanog potprograma smeta se adresa povratka u glavni program. U ovom primeru ta adresa je
#here + 20, gde je #here adresa tekue naredbe, vrednost brojaa naredbi (PC registra). Iza ove
naredbe generie se naredba GOTO pp.kod kojom se upravljanje prenosi na prvu naredbu
potprograma. .
U samom potprogramu generie se naredba za povratak u glavni program:
GO TO * pp.aktivacioni_slog
Za primer programa predstavljenog kodom na Slici 12.9, koji se satoji od glavnog programa i
poprograma, struktura aktivacionih slogova data je na istoj slici. Na Slici 12.10 prikazan je kod
koji e biti generisan od strne kompilatora za strategiju statike alokacije.
AKTIVACIONI SLOG ZA P
Za troadresni kod quicksort programa dat na Slici 12.11. bie generisana sekvenca naredbi data
na Slici 12.12.
/* kod za q
*/
action4
call p
action5
call q
action6
call q
return
Slika 12.11 Troadresni kod quicksort programa
/* Kod za proceduru s */
100: MOV #600, SP /* inicijalizacija steka */
108 : ACTION1
128: ADD #ssize, SP /* poziv potprograma */
136: MOV #152, *SP /* adresa povratka ide u stek */
144: GO TO 300 /* skok na pocetak pp q */
152: SUB #ssize, SP /* obnavljanje SP */
180 HALT