Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C-kääntäjä ja paikalliset muuttujat (kokeneille))

ljlassi [26.12.2010 20:12:17]

#

Tuli tässä mieleen, että miten C-kääntäjä käsittelee paikallisia (local) muuttujia, tallentaako se ne prosessorin rekistereihin vai suoraan keskusmuistiin?

Olis kanssa kiva tietää (jos joku tietää) alottaako C-kääntäjä uuden funktion kun kutsut jotain kirjaston komentoa vai lisääkö se tavallaan koodin saman funktion sisälle niin kuin assembly ohjelmoinnissa tehdään yleensä. Silloinhan jos se lataisi esim: printf funktion samalla tavalla kuin alifunktion niin kaikki muuttujat jouduttaisiin siirtämään keskusmuistiin.

Metabolix [26.12.2010 20:38:47]

#

Kääntäjän toiminta riippuu kääntäjästä ja sen optimointiasetuksista. Ilman optimointiasetuksia kääntäjä tavallisesti tallentaa kaikki muuttujat keskusmuistiin, jotta debuggaaminen olisi helpompaa. Yleensä jo ensimmäinen optimointitaso (GCC:llä -O tai -O1) saa aikaan sen, että arvoja pidetään mahdollisuuksien mukaan vain rekistereissä.

Omassa koodissa voi käyttää sanaa inline merkitsemään pientä funktiota, joka kääntäjän ehkä kannattaisi siirtää kuvaamallasi tavalla suoraan kutsupaikalle. Toisaalta nykykääntäjät osaavat homman luultavasti paremmin kuin nykykoodarit, ja ainakin GCC tunnistaa sopivat funktiot ihan itse inline-sanasta riippumatta esimerkiksi optimointiasetuksella -O2.

Useissa funktioissa tehdään niin mutkikkaita asioita, ettei rekisterien käyttö parametrien siirtoon ole hyödyksi. Esimerkiksi mainitsemasi printf-funktio on niin mutkikas (ja kutsuu sisäisesti monia muita funktioita), että ei ole mitään merkitystä, miten parametrit siirretään. Monissa yksinkertaisissa funktioissa (kuten memcpy tai strlen) tilanne on toki toinen, ja niiden kohdalla kääntäjä saattaakin vaihtaa funktiokutsun suoraan vastaavaksi koodiksi.

Perinteisesti x86-prosessorilla funktioiden kaikki parametrit tallennetaan keskusmuistiin, ja funktion paluuarvo palautetaan joko eax-rekisterissä (jos se on kokonaisluku tms.), ylimmässä FPU:n rekisterissä (jos se on liukuluku) tai keskusmuistissa (jos se on esimerkiksi kookas rakenne). Eri kääntäjillä on kuitenkin omia poikkeavia kutsutapojaan, joissa hyödynnetään enemmän rekistereitä, ja myös x86-64:ssä on menty melkoisesti tähän suuntaan. Lisää eri kutsutavoista voi lukea Wikipediasta.

Kirjastojen funktiot eivät nykyään yleensä sisälly ohjelmaan (edes käännetyssä muodossa) vaan sijaitsevat täysin erillisessä tiedostossa (esim. Windowsin DLL-tiedostot). Yksi syy tälle on, että näin kirjasto voidaan päivittää (ja esim. kirjaston bugeja korjata) ilman, että sitä käyttäviä ohjelmia tarvitsee kääntää uudestaan.

ljlassi [27.12.2010 00:41:23]

#

Kiitoksia hyvästä vastauksesta

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta