Viiteparametrit ja ulostuloparametrit
Viiteparametrit
Viiteparametrien käyttäminen on usein ainoa järkevä tapa välittää rakenteista tietoa aliohjelmille. Usein rakenteinen tieto on sen verran suurta, että sitä ei haluta kopioida moneen kertaan. Toisaalta taas joidenkin järjestelmien aliohjelmien toteutus voi olla tehokkuussyistä rakennettu niin, että aktivointitietueen (AT) koko on rajattu. Jotkut ohjelmointikielet antavat myös parametreille kokorajoituksia, jolloin parametrit (ja paluuarvo) voivat olla ainoastaan yksinkertaisia tietotyyppejä. Joissakin ohjelmointikielissä sallitaan esim. taulukoiden käyttö parametreina, mutta ne voi silti käytännössä olla toteutettu viiteparametrien avulla.
Aivan samalla tavalla myös suuret paikalliset tietorakenteet kasvattavat AT:n kokoa huomattavasti, mikä voi vaikuttaa merkittävästi toteutuksen tehokkuuteen. Tämän vuoksi jotkut ohjelmointikielet rajaavat myös AT:hen talletettavien paikallisten tietorakenteiden kokoa.
Käytämme tässä esimerkkinä funktiota fB(r,s,t), joka palauttaa arvonaan lausekkeen x*y+z arvon. Parametri x on arvoparametri. Parametrit y ja z ovat viiteparametreja. Funktiota fB käytetään lauseen t = fB(r,s,t) toteutuksessa, kun r, s ja t ovat globaaleja muuttujia. Funktion kutsu on hyvin samanlainen kuin aikaisemminkin, mutta nyt funktiolle välitetään s:n ja t:n osoitteet. Viiteparametri voi olla tavallinen yksinkertainen muuttuja, mutta usein viiteparametrilla välitetään rakenteista tietoa.
r dc 24
s dc 56
t dc 77
pt dc 0 ; osoitin, joka tulee osoittamaan t:hen
...
load r1, =t
store r1, pt ; alusta osoitinmuuttuja pt
...
;
; toteuta lause t = fB(r,s,t)
;
push sp, =0 ; tila paluuarvolle
push sp, r ; r:n arvo
push sp, =s ; s:n osoite
push sp, pt ; pt:n arvo eli t:n osoite
call sp, fB
pop sp, r1
store r1, t
Viiteparametreihin viittaamisessa täytyy muistaa, että parametrina on annettu vasta viitattavan tiedon osoite eikä sen arvoa. Yksinkertaiseen tietoon viittaus on silti helppo toteuttaa epäsuoraa tiedonosoitusmoodia käyttäen. Helppo tapa pitää viiteparametrit erillään arvoparametreista on nimetä ne vähän eri tavalla.
;
; funktio fB(x,y,z). X on arvoparametri. Y ja Z ovat viiteparametreja.
;
retfB equ -5 ; paluuarvon suhteellinen osoite
parX equ -4 ; arvoparametrin X suhteellinen osoite AT:ssä
vparY equ -3 ; viiteparametrin Y suhteellinen osoite AT:ssä
vparZ equ -2 ; viiteparametrin Z suhteellinen osoite AT:ssä
fB push sp, r1 ; talleta r1
load r1, parX(fp) ; laske X*Y+Z
mul r1, @vparY(fp) ; huomaa epäsuoran tiedonosoitusmoodin käyttö
add r1, @vparZ(fp)
store r1, retfB(fp) ; talleta paluuarvo
pop sp, r1 ; palauta r1
exit sp, =3
Yksiulotteisiin taulukoihin viittaaminen aliohjelmissa on vaikeampaa kuin pääohjelmatasolla, koska kaikki viittaukset täytyy tehdä osoitinmuuttujien kautta. Emme voi suoraan hyödyntää indeksoitua tiedonosoitusmoodia. Esimerkiksi, jos viiteparametrina on annettu taulukon T osoite, niin lauseen r1=T[r2] toteutus vaatii erikseen viitatun taulukon alkion sijainnin laskemisen.
...
load r3, vparT(fp) ; parametritaulukon T osoite
add r3, r2 ; alkion T[r2] osoite
load r1, 0(r3) ; alkion T[r2] arvo
...
Sen sijaan tietueisiin viittaaminen viiteparametrin kautta toimii ihan samalla tavalla kuin pääohjelmatasollakin. Esimerkkinä on tyyppiä Person oleva tietue, jonka kentät ovat Number, Age ja Salary. Aliohjelman parametri vparP osoittaa tyyppiä Person olevaan tietueeseen.
...
Number equ 0 ; kentän Number suhteelinen sijainti tietueessa
Age equ 1
Salary equ 2
...
load r3, vparP(fp) ; viitatun tietueen osoite
load r1, Age(r3) ; kentän Age arvo
...
Ulostuloparametrit
Ulostuloparametrit ovat tavallisia viiteparametreja, joita käytetään parametrina välitetyn tietorakenteen muokkaamiseen. Esimerkiksi aikaisemmin mainitun kuvan käsittelyn yhteydessä tämän on selvästi järkevin vaihtoehto, koska näin vältetään suurehkon kuvan kopiointi jokaisen kuvankäsittelyrutiinin kutsun ja paluun yhteydessä.
push sp, =0 ; paluuarvo
push sp, =photo ; manipuloitava kuva
push sp, =op1 ; haluttu kuvankäsittelyoperaatio
call sp, photoedit
pop sp, r1
jneq r1, badresult
Useissa ohjelmointikielissä rajataan funktion paluuarvon tyyppi yksinkertaiseen tietotyyppiin. Tällaisissa tapauksissa moniarvoisen funktion voi helposti toteuttaa käyttämällä useaa ulostuloparametria.
vparX equ -4
vparY equ -3
vparZ equ -2
S pushr sp ; talleta rekisterit
...
... ; laske tulokset rekistereihin r1, r2, r3
...
store r1, @vparX(fp) ; palauta tulokset viiteparametrien kautta
store r2, @vparY(fp)
store r3, @vparZ(fp)
popr sp
exit sp, =3
Viiteparametrien riskit
Toisaalta jokainen viiteparametri voi olla riski, koska sen kautta aliohjelma pääsee muuttamaan kutsuvan rutiinin dataa. Esimerkiksi, jos henkilörekisterin palkkataulukko annetaan parametrina tulostusrutiinille, niin olisi toivottavaa, että tulostusrutiini ei muuta käyttäjien palkkatietoja samalla. Tällaista hyökkäystä vastaan voi suojautua käyttämällä vain luotettavissa kirjastoissa olevia tulostusrutiineja.
Joissakin ohjelmointikielissä kaikki merkkijonot välitetään viiteparametreina, jolloin aliohjelmat voisivat manipuloida parametreina annettuja merkkijonoja haluamikseen. Tältä voidaan suojautua tallettamalla merkkijonot read only -muistialueelle ja rajaamalla merkkijonojen käsittely luotettaville kirjastoaliohjelmille.
Muistathan tarkistaa pistetilanteesi materiaalin oikeassa alareunassa olevasta pallosta!