Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

Samankaltaiset tiedostot
Konekielinen ohjelmointi

Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

4. Lausekielinen ohjelmointi 4.1

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Tiedon esitysmuodot. Luento 6 (verkkoluento 6) Lukujärjestelmät Kokonaisluvut, liukuluvut Merkit, merkkijonot Äänet, kuvat, muu tieto

Java-kielen perusteet

Luento 1 Tietokonejärjestelmän rakenne

Luento 1 Tietokonejärjestelmän rakenne

Luento 1 Tietokonejärjestelmän rakenne. Järjestelmän eri tasot Laitteiston nopeus

Luento 1 Tietokonejärjestelmän rakenne. Järjestelmän eri tasot Laitteiston nopeus

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

2 Konekieli, aliohjelmat, keskeytykset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Luento 1 (verkkoluento 1) Tietokonejärjestelmä

Luento 1 (verkkoluento 1) Ohjelman sijainti Ohjelman esitysmuoto Laitteiston nopeus

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100

Ohjelmoinnin perusteet Y Python

11/20: Konepelti auki

Ohjelmoinnin perusteet Y Python

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Java-kielen perusteet

System.out.printf("%d / %d = %.2f%n", ekaluku, tokaluku, osamaara);

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 30. marraskuuta 2015

Harjoitustyö: virtuaalikone

Laitteistonläheinen ohjelmointi

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Harjoitus 3 (viikko 39)

System.out.printf("%d / %d = %.2f%n", ekaluku, tokaluku, osamaara);

Python-ohjelmointi Harjoitus 2

Ohjelmoinnin perusteet Y Python

811120P Diskreetit rakenteet

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

Laitteistonläheinen ohjelmointi

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Ohjelmoinnin perusteet Y Python

4. Lausekielinen ohjelmointi 4.1

Luento 3 (verkkoluento 3) Ttk-91 konekielinen ohjelmointi. Ohjelman esitysmuoto Konekielinen ohjelmointi ttk-91:llä (Titokone, TitoTrainer)

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

TIES325 Tietokonejärjestelmä. Jani Kurhinen Jyväskylän yliopisto Tietotekniikan laitos

13. Loogiset operaatiot 13.1

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Teemun juustokakku Rekisterien, välimuistin, muistin, levymuistin ja magneettinauhan nopeudet suhteutettuna juuston hakuaikaan juustokakkua tehdessä?

Kertausluento luennoista 1-3 1

3. Muuttujat ja operaatiot 3.1

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. IX Suunnittelumallit Proxy, Factory Method, Prototype ja Singleton

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit.

Ohjelmoinnin perusteet Y Python

etunimi, sukunimi ja opiskelijanumero ja näillä

Johdanto. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 8. syyskuuta 2009 TIETOTEKNIIKAN LAITOS. Johdanto. Luennoija.

.NET ajoympäristö. Juha Järvensivu 2007

Kertausluento 1 (lu01, lu02, lu03) Tietokonejärjestelmän rakenne ttk-91 ja sillä ohjelmointi


Tietokoneen toiminta, Kevät Copyright Teemu Kerola Järjestelmän eri tasot Laitteiston nopeus

Tieto ja sen osoite (3) Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI) Osoitinmuuttujat. Tieto ja sen osoite (5)

Ohjelmoinnin perusteet Y Python

Haskell ohjelmointikielen tyyppijärjestelmä

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Ohjelmointiharjoituksia Arduino-ympäristössä

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

PERL. TIE Principles of Programming Languages. Ryhmä 4: Joonas Lång & Jasmin Laitamäki

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. lokakuuta 2016

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. joulukuuta 2015

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

Eloisuusanalyysi. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 16. marraskuuta 2009 TIETOTEKNIIKAN LAITOS. Eloisuusanalyysi.

Ohjelmoinnin perusteet Y Python

Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

Samanaikaisuuden hallinta

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

TIE PRINCIPLES OF PROGRAMMING LANGUAGES Eiffel-ohjelmointikieli

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

PRINCIPLES OF PROGRAMMING LANGUAGES - DEBUGGER

Ohjelmoijan binaarialgebra ja heksaluvut

Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

Luento 4 (verkkoluento 4) Aliohjelmien toteutus

Java-kielen perusteita

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Ohjausjärjestelmien jatkokurssi. Visual Basic vinkkejä ohjelmointiin

ITKP102 Ohjelmointi 1 (6 op)

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat ja operaatiot

Luento 4 (verkkoluento 4) Aliohjelmien toteutus

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 17. marraskuuta 2009

ITKP102 Ohjelmointi 1 (6 op)

Paavo Räisänen. Ohjelmoijan binaarialgebra ja heksaluvut.

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

Luento 4 Aliohjelmien toteutus

7.4 Sormenjälkitekniikka

7. Näytölle tulostaminen 7.1

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

Ohjelmointikielten periaatteet. Antti-Juhani Kaijanaho

7/20: Paketti kasassa ensimmäistä kertaa

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Transkriptio:

Ohjelmointikielten periaatteet Syksy 2004 Antti-Juhani Kaijanaho

Copyright c 2002, 2004 Antti-Juhani Kaijanaho Tästä teoksesta saa valmistaa kappaleita ja sen saa saattaa yleisön saataviin, muuttamattomana tai muutettuna, käännöksenä tai muunnelmana, toisessa kirjallisuus- tai taidelajissa taikka toista tekotapaa käyttäen, mikäli kaikki seuraavat ehdot tulevat täytetyksi: (1) Kun teoksesta valmistetaan muutettu kappale tai muutettu teos kokonaan tai osittain saatetaan yleisön saataviin, on teoksen muuttajan nimi, salanimi tai nimimerkki ilmoitettava tekijän nimen rinnalla. (2) Kun teoksesta valmistetaan muutettu kappale tai muutettu teos kokonaan tai osittain saatetaan yleisön saataviin, on pidettävä huoli, ettei muutettua teosta voi hyvällä tahdolla sekoittaa alkuperäiseen. (3) Teoksen tekijän nimeä ei saa ilman hänen eri lupaansa käyttää teoksen markkinoinnissa. Erikseen korostettakoon, että teoksen tekijä ei vaadi maksua teoskappaleiden valmistamisesta tai teoksen saattamisesta yleisön saataviin. Teoskappaleen valmistaja tai teoksen yleisön saataviin saattaja saa periä tästä haluamansa maksun. Tekijänoikeuslaki (404/1961) 3 1 mom: Kun teoksesta valmistetaan kappale tai teos kokonaan tai osittain saatetaan yleisön saataviin, on tekijä ilmoitettava sillä tavoin kuin hyvä tapa vaatii.

Esipuhe Sisältö Luku 1. Johdanto 1 1. Kielten jaotteluja 1 2. Kielen valinta 6 3. Ohjelmointikielten suunnitteluperiaatteita 7 4. Kielen määrittely 8 5. Toteutustekniikoista 10 Osa 1. Imperatiivinen ohjelmointi 11 Luku 2. Konekielinen ohjelmointi 13 1. Konekielet 13 2. Symboliset konekielet 15 3. Abstraktit koneet 16 4. Neloskielen idea 18 5. Systeemikutsut 23 6. Konekielellä ohjelmoinnista 24 Luku 3. Suoraviivaohjelmat 27 1. Suoraviivaohjelman elementit 27 2. Abstrakti syntaksi 35 3. Denotationaalinen semantiikka 38 4. Tyyppijärjestelmä 46 5. Konkreetti kielioppi 51 6. Toteutuksesta 57 Luku 4. Paikallinen kontrollivuon ohjaus 61 1. 61 Luku 5. Epädeterministinen ohjelmointi 63 Luku 6. Samanaikaisuus 65 1. Jaettu muisti 65 2. Erilliset kommunikoivat prosessit 65 Luku 7. Aliohjelma-abstraktio 67 Osa 2. Applikatiivinen ohjelmointi 69 Luku 8. Funktioabstraktio 71 iii v

iv SISÄLTÖ Luku 9. Tyypitys 73 Luku 10. Rakenteiset arvot 75 Luku 11. Synteesi 77 Osa 3. Laajuuden hallinta 79 Luku 12. Abstraktit tietorakenteet ja modulit 81 Luku 13. Olioabstraktio 83 Luku 14. Polymorfismi 85 Kirjallisuutta 87 Liite A. Neloskoneen systeemikutsut 89 Liite B. Ohjelmointikielten historia 95 1. Kaksi ensimmäistä sukupolvea: ennen vuotta 1955 95 2. Automaattinen ohjelmointi ja ohjelmointikielten synty: 1955 1960 95 3. Baabelin torni: 1960-luku 97 4. Modernismi: 1970-luku 98 5. Postmodernismi: 1980-luku 99 6. Internetin nousu: 1990-luku 100 7. Sukupolvista 100 Liite C. Semanttiset alueet 101 1. Tuloalueet 103 2. Summa-alueet 104 3. Funktioalueet 106 Liite D. ALKEIS-suoran kääntäjä 109 1. Pääohjelma 109 2. Selain 113 3. Apuluokat 119 4. Lauseet 122 5. Tyypit 128 6. Lausekkeen jäsennin 135 7. Primäärilausekkeet 138 8. Operaattorilausekkeet 142 9. Muunnoslausekkeet 147

Osa 1 Imperatiivinen ohjelmointi

LUKU 2 Konekielinen ohjelmointi Tässä luvussa käsitellään konekielistä ohjelmointia ja esitellään kuvitteellinen kone, jonka avulla monisteessa myöhemmin esitellään eri kieliominaisuuksien toiminta. 1. Konekielet Konekielellä tarkoitetaan sitä kieltä, jota tietokone ymmärtää suoraan. Koska kaikki nykytietokoneet perustuvat samaan ideaan siitä, miten tietokone toimii (ns. von Neumannin kone), ovat myös eri koneiden konekielet suurpiirteisesti katsoen samanlaisia. Yhteistä kaikille konekielille on se, että ne eivät ole tekstuaalisia vaan asiat ilmaistaan konekielellä koodaamalla ne jollakin annetulla tavalla tavujonoksi 1, jota sitten koneen prosessori tulkitsee. Yhteistä myös kaikille konekielille on se, että ohjelmat voidaan jäsentää dataksi ja koodiksi, ja koodi voidaan edelleen jäsentää jonoksi käskyjä (engl. instructions), jotka viittaavat dataan ja muualle koodiin. Käskyt puolestaan voidaan luokitella karkeasti seuraavasti: (1) datan siirto (2) kokonaislukuaritmetiikka (3) vertailu (4) ehdolliset hypyt (5) ehdottomat hypyt (6) järjestelmäkutsut (7) sovellusaluekohtaiset käskyt (8) järjestelmäkäskyt Näistä viisi ensimmäistä käskyluokkaa ovat jatkuvassa käytössä kaikissa ohjelmissa. Järjestelmäkutsujakin käytetään kaikissa ohjelmissa, mutta niiden käyttötaajuus vaihtelee. Järjestelmäkäskyjä eivät tavalliset ohjelmat kykene käyttämään, ne ovat olemassa käyttöjärjestelmien tarpeita varten. Useimmat tietokoneet tarjoavat lisäksi koko joukon erilaisia sovellusaluekohtaisia käskyjä; näistä lähes yleiskäyttöisen aseman on saanut liukulukukäskyt, pöytäkoneissa tavallisia 1 Tavu (engl. byte) ei välttämättä ole kahdeksanbittinen, vaikka nykykoneissa näin onkin. Huolitellussa kielenkäytössä tavu tarkoittaa koneen pienintä osoitettavissa olevaa tietoyksikköä; jos halutaan puhua nimenomaan kahdeksanbittisestä tietoyksiköstä, korrekti termi on oktetti. 13

14 2. KONEKIELINEN OHJELMOINTI ovat erilaiset reaaliaikagrafiikan piirtämisessä tarvittavat laskentamenetelmät (esimerkiksi SIMD ja MMX). Yleensä konekielissä on jokin varsin yksinkertainen mekanismi, jolla eri käskyt voidaan erottaa toisistaan. Vanhoissa, ns. CISC-malleissa 2 käskyn aloitti yleensä ns. operaatiokoodi (engl. opcode), joka yleensä vei yhden tavun. Operaatiokoodi ilmaisi, mistä käskystä oli kyse sekä mistä löytynyttä dataa käsky käsitteli. Operaatiokoodia seurasi vaihteleva määrä operandeja, jotka tarkensivat datan sijaintia (antaen esimerkiksi kiinteän osoitteen, mistä data löytyy). Uudemmissa RISC-maleissa 3 käskyt ovat yleensä kiinteämittaisia (esimerkiksi neljän tavun mittaisia riippumatta käskystä) sekä sisältävät operaatiokoodin ja yhden tai useamman operandin. Vaikka konekielet ovatkin suurpiirteisesti katsoen samanlaisia, niiden välillä on huomattavia eroja yksityiskohdissa. Pääsääntöisesti vain samanlaiselle koneelle tarkoitettu konekielinen ohjelma toimii toisessa koneessa. Eri prosessorit jaotellaan sen mukaan, toimivatko toiselle kirjoitetut ohjelmat toisessa prosessorissa. Keskeinen käsite on käskykanta-arkkitehtuuri (engl. instruction set architecture), joka määrää, mitä käskyjä prosessori tukee. Tällä hetkellä merkittävät käskykanta-arkkitehtuurit ovat IA-32: Ehkäpä kaikkien aikojen menestynein käskykanta-arkkitehtuuri: Lähes kaikki nykyiset pöytäkoneet ja kannettavat perustuvat IA-32:lle. Myös monet vähäistä tai keskinkertaista tehoa vaativat palvelimet käyttävät IA-32:a. Ensimmäinen prosessori, joka tuki tätä käskykantaa, oli Intelin 80-386 vuodelta 1985. Myöhemmät prosessorit ovat laajentaneet käskykantaa, mutta sen ydin on edelleen sama, jota 80-386 tuki. IA-32:ta tukevia prosessoreita valmistavat lähinnä Intel ja AMD, mutta on muitakin valmistajia. Kuten tietokonealalla yleensäkin on tapana, markkinajohtaja IA-32 ei ole teknisesti paras markkinoilla olevista vaihtoehdoista. AMD64: AMD:n suunnittelema uusi (2003) käskykanta-arkkitehtuuri, joka on IA-32:n laajennus samassa mielessä kuin IA-32 itse oli aiempien Intel 8086- ja 80286-arkkitehtuurien laajennus. Vaikka AMD64 on varsin nuori, sen odotetaan seuraavien vuosien korvaavan IA-32:n. Kuten IA-32:ta, AMD- 64:ää tukevia prosessoreita valmistavat sekä AMD (Athlon64 ja Opteron) että Intel (EM64T). 2 Complex Instruction Set Computer; valtaosassa pöytäkoneita käytettävä Intelin 32-bittinen prosessoriarkkitehtuuri IA-32 (80386, Pentium ym.) kuuluu tähän luokkaan historiansa vuoksi. 3 Reduced/Regular Instruction Set Computer; näitä ovat käytännössä kaikki 1980-luvun loppupuolella tai sitä myöhemmin puhtaalta pöydältä suunnitellut prosessoriarkkitehtuurit; esimerkiksi Sparc, Alpha ja mobiililaitteista usein löytyvä ARM.

2. SYMBOLISET KONEKIELET 15 PowerPC: Applen, IBM:n ja Motorolan yhteishankkeena 1990- luvun alussa lanseeraama käskykanta-arkkitehtuuri, jota käyttävät nykyisin lähinnä uudehkot Macintosh-koneet. ARM: ARM on suhteellisen suurta laskentatehoa tarvitsevien sulautettujen järjestelmien (esimerkiksi mobiilipäätelaitteet) ja kämmenmikrojen prosessorien käskykanta-arkkitehtuuri. ARM-yhteensopivia prosessoreita valmistaa moni mikroprosessorivalmistaja. MIPS: Merkittävä suurta laskentatehoa vaativien sulautettujen ja mobiilien järjestelmien prosessorien käskykanta-arkkitehtuuri; käytössä myös SGI:n työasemien prosessoreissa. Sparc: Suosittu käskykanta-arkkitehtuuri palvelinkäytössä. Alkuperäinen Sparc on 32-bittinen; sen 64-bittinen laajennus on nimeltään UltraSparc. 2. Symboliset konekielet Konekieltä ei juuri koskaan kirjoiteta käsin. Konekieliset ohjelmat syntyvät yleensä varsinaisten ohjelmointikielten kääntäjien vasteena. Toisinaan kuitenkin ohjelmoija haluaa kirjoittaa samalla abstraktiotasolla, jonka konekieli tarjoaa. Tällaisia tilanteita varten jokaiseen konekieleen liittyy symbolinen konekieli (engl. assembly). Se on konekielisen ohjelman tekstuaalinen esitysmuoto, jossa kukin käsky on omalla rivillään, osoitteiden sijasta käytetään symbolisia nimiä ja jossa käskyn toimittama operaatio ja sen operandit on selvästi erotettu toisistaan. Symbolisella konekielellä kirjoitetun ohjelman kääntämiseen varsinaiselle konekielelle tarvitaan oma ohjelmansa (tosin onnistuu se kyllä käsinkin), ns. assembler 4. Lähes kaikilla symbolisilla konekielillä on sama perusrakenne. Kuten edellä jo todettiin, kukin käsky on omalla rivillään. Pystysuunnassa symbolisella konekielellä kirjoitettu ohjelma jakautuu sarakkeisiin, joiden avulla käskyn eri osat jäsentyvät. Tavallisesti käskyn osoitetta edustava symbolinen nimi, ns. label, on ensimmäisessä sarakkeessa. Jos sellaista ei ole, ensimmäinen sarake on tyhjä. Toinen sarake on varattu käskyn muistikkaalle (engl. mnemonic) yleensä kolmikirjaiminen, joskus kaksi- tai nelikirjaiminen tunnus, joka nimeää käskyn. Kolmas, neljäs ja joskus viideskin sarake on käskyn operandien käytössä. Tämän tarkemmin ei symbolisia konekieliä voi kuvata yleisesti, sillä jokaisella symbolisella konekielellä on omat merkintätapansa. Tavallisesti kullakin käskykanta-arkkitehtuurilla on täsmälleen yksi symbolinen konekieli; IA-32 on tästä poikkeus, sillä on nimittäin niitä kaksi: AT&T:n ja Intelin symboliset konekielet. 4 Huomaa: assembly on kieli, assembler ohjelma.

16 2. KONEKIELINEN OHJELMOINTI unsigned long str2ulong(char const * s) { unsigned long rv = 0; for (/**/; *s!= 0; s++) { rv = 10 * rv + (*s - '0'); } return rv; } KUVA 1. Yksinkertainen aliohjelma C-kielellä.text.p2align 4,,15.globl str2ulong.type str2ulong, @function str2ulong: pushl %ebp xorl %edx, %edx movl %esp, %ebp movl 8(%ebp), %ecx movzbl (%ecx), %eax testb %al, %al je.l8.p2align 4,,15.L6: movsbl %al,%eax incl %ecx leal (%edx,%edx,4), %edx leal -48(%eax,%edx,2), %edx movzbl (%ecx), %eax testb %al, %al jne.l6.l8: popl %ebp movl %edx, %eax ret KUVA 2. Yksinkertainen aliohjelma IA32-arkkitehtuurin symbolisella konekielellä (AT&T) Kuvissa 2, 3 ja 4 on kuvattu yksinkertainen aliohjelma kolmella eri symbolisella konekielellä. Vastaava C-kielinen aliohjelma on kuvassa 1. 3. Abstraktit koneet Abstrakti kone on käskykanta-arkkitehtuuri, jota ei ole tarkoitettu toteutettavaksi suoraan laitteistossa. Jos abstaktilla koneella on ohjelmistototeutus, se on virtuaalikone.

3. ABSTRAKTIT KONEET 17.section ".text".align 4.global str2ulong.type str2ulong, #function.proc 016 str2ulong:!#prologue# 0!#PROLOGUE# 1 ldub [%o0], %o4 sll %o4, 24, %g1 cmp %g1, 0 be.ll8 mov 0, %o3 mov %g1, %o4.ll6: add %o0, 1, %o0 ldub [%o0], %g1 sra %o4, 24, %o5 sll %g1, 24, %g1 orcc %g1, 0, %o4 sll %o3, 2, %g1 add %g1, %o3, %g1 add %g1, %g1, %o3 add %o3, %o5, %g1 bne.ll6 add %g1, -48, %o3.ll8: retl mov %o3, %o0 KUVA 3. Yksinkertainen aliohjelma UltraSparc-arkkitehtuurin symbolisella konekielellä Ohjelmoijan näkemä tietokone on harvoin täsmälleen se, jonka tietokoneen laitteisto toteuttaa. Yleensä ohjelmoija voi luottaa käyttöjärjestelmän palveluihin. Käyttöjärjestelmä siis rakentaa fyysisen tietokoneen päälle eräänlaisen virtuaalisen tietokoneen, siis virtuaalikoneen. Joskus ohjelmoijan kirjoittamaa ohjelmaa suorittaa simulaattori, joka imitoi jotain abstraktia konetta; tällöin ohjelmoijan näkemä kone on tyystin toinen kuin mitä laitteistosta voisi päätellä. Tällainen tilanne on esimerkiksi silloin, kun Java-ohjelmaa ajetaan Java-virtuaalikoneessa. Tämän luvun loppuosa esittelee erään abstraktin koneen, joka on eräänlainen todellisten koneiden idealisaatio, ja se tarjoaa jonkin verran myös käyttöjärjestelmältä odotettavia palveluita. Ideana on, että myöhemmin tässä monisteessa voidaan sitten pohtia kehittyneempien ohjelmointikielten toteutusta tämän abstraktin koneen tarjoamassa viitekehyksessä ilman, että tarvitsee miettiä sellaisia kääntäjätekniikan inhottavuuksia kuten rekisterien valintaa.

18 2. KONEKIELINEN OHJELMOINTI.section ".text".align 2.globl str2ulong.type str2ulong,@function str2ulong: mr 11,3 lbz 0,0(11) li 3,0 cmpwi 0,0,0 bclr 12,2.L6: slwi 9,3,3 add 9,9,3 add 9,9,3 addi 9,9,-48 add 3,0,9 lbzu 0,1(11) cmpwi 0,0,0 bc 4,2,.L6 blr KUVA 4. Yksinkertainen aliohjelma PowerPC-arkkitehtuurin symbolisella konekielellä 4. Neloskielen idea Neloskieli on erään abstraktin koneen symbolinen konekieli. Ennen kuin voidaan puhua itse kielestä, pitää hahmotella kyseinen abstrakti kone. Olkoon se nimeltään Neloskone. Neloskoneen rakenne on kaksijakoinen: sillä on muisti ja prosessointiyksikkö. Neloskoneen muisti on 2 32 tavun taulukko; tavun koko on tavanomaiset kahdeksan bittiä. Jokaisella muistin tavulla on yksikäsitteinen osoite, joka on 32-bittinen etumerkitön kokonaisluku. Muisti jakautuu viiteen osaan: tekstimuistiin, datamuistiin, nollamuistiin, käyttämättömän muistin alueeseen sekä pinomuistiin. Kukin muistin osa on yhtenäinen osa muistia. Tekstimuisti alkaa aina osoitteesta 0, datamuisti heti tekstimuistin jälkeen ja nollamuisti heti datamuistin jälkeen. Nollamuistin jälkeen alkaa käyttämättömän muistin alue, jota ei saa lukea ja johon ei saa kirjoittaa. Muistin lopussa on pinomuisti, joka päättyy osoitteeseen 2 32 1. Kunkin

4. NELOSKIELEN IDEA 19 muistialueen eli segmentin koko voi vaihdella käynnistyskerrasta toiseen; nollamuistin ja pinomuistin koko voi vaihdella myös suorituksen aikana. Tekstimuistiin kirjoittaminen on kiellettyä; muistipaikan, jonka osoite on 0, lukeminen on myös kiellettyä. 5 Vaikka muisti onkin tavutaulukko, sitä tavallisesti käsitellään neljän tavun eli sanan (engl. word) yksiköissä 6. Sana voidaan tilanteesta riippuen tulkita etumerkittömäksi 32-bittiseksi kokonaisluvuksi, etumerkilliseksi 32-bittiseksi kokonaisluvuksi tai yksinkertaisen tarkkuuden liukuluvuksi. Jos sanan tavut ovat x 0,..., x 3, missä x 0 on se tavu, jonka osoite on pienin, ja x 3 on se tavu, jonka osoite on suurin, sana tulkitaan seuraavasti etumerkittömäksi kokonaisluvuksi: Sanan lukuarvo etumerkittömänä kokonaislukuna on 3 i=0 256 i x i, toisin sanoen vähiten merkitsevä tavu on sanassa ensimmäisenä. Neloskone on siis little-endian; jos eniten merkitsevä tavu olisi ensimmäisenä, se olisi big-endian. etumerkilliseksi kokonaisluvuksi: Kun sana tulkitaan etumerkilliseksi kokonaisluvuksi, on sen etumerkki negatiivinen, jos sanan eniten merkitsevä bitti on 1 ja positiivinen, jos sanan eniten merkitsevä bitti on 0. Jos sanan etumerkki on negatiivinen, sanan itseisarvo saadaan, kun siihen sovelletaan ensin biteittäistä negaatiota, minkä jälkeen se tulkitaan yllä esitetysti etumerkittömäksi kokonaisluvuksi ja tulokseen lisätään 1. Positiivisen luvun arvon saamiseksi riittää soveltaa sanaan suoraan yllä esitettyä etumerkittömän luvun menetelmää. Toisin sanoen Neloskone käyttää kahden komplementti -esitystä (engl. two s complement). yksinkertaisen tarkkuuden liukuluvuksi: IEEE 754 -standardin [1] mukaisesti. Sanasta voidaan käsitellä myös vähemmän merkitsevää puolikasta, siis sitä 16-bittistä kokonaisuutta, joka koostuu sanan kahdesta ensimmäisestä tavusta. Tällainen puolisana (engl. half-word) voidaan tulkita etumerkittömäksi kokonaisluvuksi tai etumerkilliseksi 5 Tämä muistin jako segmentteihin on itse asiassa matkittu UNIX-käyttöjärjestelmien käyttämästä kullekin ohjelmalle erikseen annetun muistiavaruuden rakenteesta. Unixissa nollamuistin nimi on bss. 6 Sanan pituus vaihtelee käskykanta-arkkitehtuurista riippuen; yleensä se on kaksi, neljä tai kahdeksan tavua pitkä. Sitä sanotaan myös konesanaksi (engl. machine word).

20 2. KONEKIELINEN OHJELMOINTI kokonaisluvuksi yllä esitettyä vastaavalla tavalla. Tietyissä tilanteissa kaksi peräkkäistä sanaa muodostavat kaksoissanan (engl. doubleword), joka tulkitaan kaksinkertaisen tarkkuuden liukuluvuksi IEEE 754 -standardin mukaisesti. Kaksoissana, sana tai puolisana voidaan lukea vain alkaen neljällä jaollisista osoitteista. Ajatus on, että tekstimuisti sisältää suoritettavan ohjelman konekielisen koodin. Kukin käsky vie 16 tavua; käskyjen koodaus jätetään tarkoituksella määrittelemättä. Datamuisti sisältää kaiken ohjelman alussa varattavan ja alustettavan datan, nollamuisti sisältää kaiken ohjelman alussa varattavan ja nollaksi alustettavan datan. Koneessa pyörivä ohjelma voi lisäksi kasvattaa nollamuistin kokoa ja näin mahdollistaa dynaamisen muistinvarauksen (tosin ohjelma joutuu itse pitämään kirjaa yksittäisten dynaamisten muuttujien varauksista ja vapauttamisista). Pinomuistia ohjelma voi käyttää esimerkiksi aliohjelmien hallintaan. Koneessa on viisi 32-bittistä rekisteriä: SP: (Stack Pointer) Pienin osoite, joka kuuluu pinomuistiin. (Nolla tulkitaan siten, että pino on tyhjä.) FP: (Frame Pointer) On aina suurempi tai yhtäsuuri kuin SP. IP: (Instruction Pointer) Sisältää sen tekstimuistin tavun osoitteen, josta seuraavaksi suoritettava käsky alkaa. ZL: (Zero Limit) Pienin osoite, joka ei kuulu tekstimuistiin, datamuistiin eikä nollamuistiin. AR: (Address Register) Käytetään epäsuorien osoitusten osoitelähteenä. Kun Nelikone käynnistyy, se lataa ajettavan ohjelman jostakin tarkemmin määrittelemättömästä lähteestä. Ohjelma määrää tekstija datamuistin koon sekä nollamuistin lähtökoon sekä sen, mitä tekstimuistiin sisältyy ja mitkä ovat datamuistin tavujen alkuarvot. Ennen suorituksen alkamista kone nollaa kaikki nollamuistin tavut ja pinomuisti on tyhjä (SP on nolla). Nelikoneen käskyt on lueteltu taulukossa 1. Kukin operandi (opr1, opr2 tai opr3) voi olla [nimi], jolloin operandin sisältö luetaan alkaen muistipaikasta, jonka osoite on vakion nimi arvo; [R + n], jolloin operandin sisältö luetaan alkaen muistipaikasta, joka saadaan, kun R-rekisterin (FP, SP tai AR) sisältämään osoitteeseen lisätään vakio n (0 n < 2 32 ); sekä [R n], jolloin operandin sisältö luetaan alkaen muistipaikasta, joka saadaan, kun R-rekisterin (FP, SP tai AR) sisältämästä osoitteesta vähennetään vakio n (0 n < 2 32 ). Operandi voi myös olla jotain seuraavista, jos se ei esiinny nuolen ( ) vasemmalla puolella:

4. NELOSKIELEN IDEA 21 Käsky Kuvaus opr1 opr2 Kopioi opr2:n sisältö opr1:een. opr1 opr2 + opr3 Laita opr2:n ja opr3:n summa opr1:een. opr1 opr2 opr3 Laita opr2:n ja opr3:n erotus opr1:een. opr1 opr2 opr3 Laita opr2:n ja opr3:n tulo opr1:een. opr1 opr2 / opr3 Jaa opr2 opr3:lla ja laita osamäärä opr1:een. opr1 opr2 mod opr3 Jaa opr2 opr3:lla ja laita jakojäännös opr1:een. opr1 opr2 and opr3 Suorita biteittäinen ja-operaatio opr2:n ja opr3:n välillä ja tallenna tulos opr1:een. opr1 opr2 or opr3 Suorita biteittäinen tai-operaatio opr2:n ja opr3:n välillä ja tallenna tulos opr1:een. opr1 opr2 xor opr3 Suorita biteittäinen poissulkeva tai -operaatio opr2:n ja opr3:n välillä ja tallenna tulos opr1:een. opr1 not opr2 Suorita biteittäinen negaatio opr2:lle ja tallenna tulos opr1:een. opr1 reg Kopioi rekisterin reg (AR, SP, FP tai ZL) sisältö opr1:een. reg opr1 Kopioi rekisterin opr1:n sisältö reg:iin (AR, SP, FP tai ZL). reg1 reg2 Kopioi rekisterin reg1:n (AR, SP, FP tai ZL) sisältö reg2:een (AR, SP, FP tai ZL). SP SP + n Lisää SP:hen vakio n. SP SP n Vähennä SP:stä vakio n. if opr1 = opr2 goto opr3 Jos opr1:n ja opr2:n sisällöt ovat samat, laita opr3:n sisältö IP:hen. if opr1 < opr2 goto opr3 Jos opr1:n sisältö on pienempi kuin opr2:n sisältö, laita opr3:n sisältö IP:hen. if opr1 opr2 goto opr3 Jos opr1:n sisältö on pienempi tai yhtäsuuri kuin opr2:n sisältö, laita opr3:n sisältö IP:hen. if opr1 > opr2 goto opr3 Jos opr1:n sisältö on pienempi kuin opr2:n sisältö, laita opr3:n sisältö IP:hen. if opr1 opr2 goto opr3 Jos opr1:n sisältö on suurempi tai yhtäsuuri kuin opr2:n sisältö, laita opr3:n sisältö IP:hen. if opr1 opr2 goto opr3 Jos opr1:n ja opr2:n sisällöt ovat erisuuret, laita opr3:n sisältö IP:hen. goto opr1 Laita opr1:n sisältö IP:hen. syscall n Tee systeemikutsu, jonka tunnus on vakio n (ks. liite A). TAULUKKO 1. Nelikoneen käskykanta n, jolloin operandin sisältö on kyseinen vakio n (0 n < 2 32 ); tai nimi, jolloin operandin sisältö on se luku, jota ko. nimi edustaa. Operandi, joka on muotoa [jotain+0] tai [jotain-0] voidaan lyhentää [jotain].

22 2. KONEKIELINEN OHJELMOINTI Operandien koko ja tulkinta määräytyy käskyn mukaan. Pääsääntöisesti operandien koko on neljä tavua ja ne tulkitaan etumerkittömiksi kokonaisluvuiksi. Tämä voidaan muuttaa kirjoittamalla käskyrivin loppuun jokin seuraavista merkinnöistä: (FS): Operandit ovat nelitavuisia sanoja, jotka tulkitaan yksinkertaisen tarkkuuden liukuluvuiksi. (FD): Kukin operandi koostuu kahdesta perättäisestä nelitavuisesta sanasta, joka tulkitaan kaksinkertaisen tarkkuuden liukuluvuiksi. (S): Operandit ovat nelitavuisia sanoja, jotka tulkitaan etumerkillisiksi kokonaisluvuiksi. (H): Operandit ovat kaksitavuisia puolisanoja, jotka tulkitaan etumerkittömiksi kokonaisluvuiksi. (HS): Operandit ovat kaksitavuisia puolisanoja, jotka tulkitaan etumerkillisiksi kokonaisluvuiksi. (B): Operandit ovat tavuja, jotka tulkitaan etumerkittömiksi kokonaisluvuiksi. (BS): Operandit ovat tavuja, jotka tulkitaan etumerkillisiksi kokonaisluvuiksi. Kertolaskun tulosoperandi ja jakolaskun jaettavan sisältävä operandi on kokonaislukulaskennassa aina kaksi kertaa niin pitkä kuin muut operandit. Vertailukäskyjen kolmas operandi sekä goton ainoa operandi on kuitenkin tällaisista merkinnöistä huolimatta aina nelitavuinen sana, joka tulkitaan etumerkittömäksi kokonaisluvuksi, joka on tekstimuistiin kuuluva osoite. Bitittäisten operaatioiden (and, or, xor, not) kanssa merkinnät (FS) ja (FD) ovat kiellettyjä, sillä liukuluvun bitittäinen käsittely ei ole mielekästä. Esimerkiksi käsky [tmp] [rv] 10 (B) kertoo rv:n edustaman muistipaikan sisällön kymmenellä ja sijoittaa tuloksen puolisanaan, joka alkaa tmp:n sisältämästä osoitteesta. Symbolisessa konekielessä tulee olla myös tapa määritellä symbolisia nimiä osoitteille ja vakioille. Sovitaan niin, että rivin alussa oleva sana, jonka perässä on kaksoispiste, määrittelee kyseisen sanan symboliseksi vakioksi, jonka arvona on seuraavan käskyn osoite. Sovitaan myös, että pseudokäsky data, jonka perään kirjoitetaan yksi luku, lisää datamuistiin uuden nelitavuisen muuttujan, jonka alkuarvo on kyseinen luku. Lisäksi sovitaan, että pseudokäsky zero lisää nollamuistin kokoa neljällä tavulla (varaten näin tilaa yhdelle nolla-alusteiselle muuttujalle). Sovittakoon vielä, että pseudokäsky string, jonka perään kirjoitetaan C-tyylinen merkkijono, lisää datamuistiin tavujonon, jonka sisältö on tuo merkkijono. Pseudokäskyn osoite olkoon sen määrittelemän uuden muuttujan osoite (zeron tapauksessa nollamuistin ylärajan vanha arvo).

str2ulong: SP SP 4 [SP] FP FP SP [s] [FP + 8] [rv] 0 loop: AR [s] [tmp] 0 [tmp] [AR] (B) if [tmp] = 0 goto finish [tmp] [tmp] 48 [rv] [rv] 10 [rv] [rv] + [tmp] [s] [s] + 1 goto loop finish: [FP + 8] [rv] FP [FP] tmp [SP + 4] SP SP + 8 goto [tmp] tmp: zero s: zero rv: zero zero 5. SYSTEEMIKUTSUT 23 KUVA 5. Yksinkertainen aliohjelma Nelikielellä Lisäksi on vielä pseudokäsky noinstr, joka ei tee yhtään mitään (paitsi kertoo, että samalla rivillä oleva symbolinen nimi saa arvonsa juuri tekstimuistista). Kuvassa 5 on esitetty kuvien 1, 2, 3 ja 4 aliohjelma nelikielellä. 5. Systeemikutsut Ollakseen hyödyllinen ohjelman tulee voida vaikuttaa ympäristöönsä sekä ottaa ympäristöstään vaikutteita. Tämä tapahtuu ohjaamalla erilaisia oheislaitteita kuten näyttöä, printteriä ja hiirtä. Yleensä tavallisen ohjelman ei anneta kuitenkaan vapaasti keskustella oheislaitteiden avulla; syyt lienevät kaikille selvät. Sen sijaan käyttöjärjestelmä keskustelee laitteiden kanssa ja välittää ohjelmien pyynnöt eteenpäin huolehtien siitä, että samaan aikaan käynnissä olevat ohjelmat eivät tallo toisiaan varpaille. Käytännössä ohjelman tulee voidakseen keskustella ympäristönsä kanssa siis keskustella käyttöjärjestelmän kanssa. Tavallisesti tämä tapahtuu systeemikutsujen (engl. system calls) avulla: kun ohjelma haluaa käyttää käyttöjärjestelmän palveluita, se käyttää jotain erityistä mekanismia kutsuakseen käyttöjärjestelmää 7. 7 Toinen vaihtoehto olisi antaa käyttöjärjestelmän kutsua ohjelmaa tarvittaessa. Tätä sanottaisiin tapahtumapohjaiseksi (engl. event-based) systeemiksi. Tavallisesti todellisissa järjestelmissä käytetään tarpeen mukaan molempia järjestelyitä.

24 2. KONEKIELINEN OHJELMOINTI 0 Avaa olemassaoleva tiedosto 1 Luo uusi tiedosto ja avaa se 2 Sulje avattu tiedosto 3 Lue tiedostosta 4 Kirjoita tiedostoon 5 Muuta luku/kirjoituskohdan sijaintia (seek) 6 Kerro luku/kirjoituskohdan sijainti (tell) 7 Jakaudu (fork) 8 Kloonaudu (clone) 9 Lähetä viesti toiselle rinnalla suoritettavalle koneelle 10 Vastaanota viesti 11 Sammuta kone 12 Odota rinnakkaisen koneen sammumista 13 Aika TAULUKKO 2. Neloskoneen systeemikutsut Neloskoneen tapauksessa koneeseen on sisäänrakennettu jokunen systeemikutsu. Systeemikutsu etenee siten, että ohjelma laittaa systeemikutsun argumentit pinoon ja käyttää sitten syscall n -käskyä, missä n on halutun systeemikutsun tunnus. Neloskoneen käyttöjärjestelmä poistaa argumentit pinosta ja laittaa tilalle paluutiedon, sekä suorittaa halutun toiminnon, mikäli se on mahdollista. Neloskoneen tapauksessa kolme parametria ottava ja yhden paluutiedon antava systeemikutsu etenee siis suunnilleen näin: SP SP 12 [SP + 8] parametri3 [SP + 4] parametri2 [SP + 0] parametri1 syscall n [paluutiedon paikka] [SP + 0] SP SP + 4 Tässä n on halutun systeemikutsun tunnusnumero. Taulukossa 2 on lyhyesti esitetty Neloskoneen systeemikutsut. Tarkemmin ne esitellään liitteessä A. Tässä vaiheessa systeemikutsujen tarkka toiminta ei ole oleellista; niihin palataan myöhemmin. 6. Konekielellä ohjelmoinnista Symbolisella konekielellä ohjelmointi voi olla tottumattomalle outoa, joten sanotaan sananen siitä.

6. KONEKIELELLÄ OHJELMOINNISTA 25 Symbolisella konekielellä ohjelmoinnin kaksi tärkeintä eroa korkean tason kielillä ohjelmointiin nähden on, että konekielellä joudutaan kaikki kontrollirakenteet kirjoittaa gotoa tai muuta vastaavaa menetelmää käyttäen ja että lausekkeet joudutaan käsin purkamaan osaoperaatioihinsa (päättäen samalla, minne välitulokset tallennetaan). Näinpä konekieliohjelmointi on hyvinkin matalan tason näperöintiä ja se kannattaa pääosin jättää kääntäjän huoleksi. Yksi asia, joka saattaa tuntua oudolta korkean tason ohjelmointikieliin tottuneesta, on tietotyyppien erilainen tulkinta. Lähes kaikissa korkean tason kielissä jokaiseen tiedonpalaseen liittyy tyyppi, joka kertoo, mitä operaatioita sille saa tehdä ja miten se pitää tulkita arvoksi; monissa asetetaan vielä rajoitus, jonka mukaan muuttuja voi pitää sisällään vain yhden tyyppisiä tiedonpalasia. Symbolisessa konekielissä tiedonpalalla ei ole mitään sisäsyntyistä tyyppiä; jokaiselle tiedonpalaselle voi periaatteessa tehdä mitä vain, ja valittu operaatio kertoo, minkä tyypin mukaisena sitä käsitellään. Nelikielellä kirjoitettavien ohjelmien muistinkäyttöön sopii seuraavat ohjeet: (1) Pinomuistia käytetään vain silloin, kun se on välttämätöntä. (2) Paikalliset ja väliaikaiset muuttujat sijoitetaan nollamuistiin zero-pseudokäskyllä. (3) Alustetut globaalit muuttujat sijoitetaan datamuistiin datapseudokäskyllä. Konekieliohjelmointia jo tuntevat ihmetellevät jo, mitä tehdään, kun nelikielessä ei ole yleiskäyttöisiä rekistereitä. Ajatus on, että nollamuistiin sijoitettavat paikalliset muuttujat täyttävät sen tehtävän, mihin normaalisti käytettäisiin yleiskäyttöisiä rekistereitä. TEHTÄVÄ 2.1. Koeta kirjoittaa nelikielinen ohjelma, joka lukee näppäimistöltä (stdin) käyttäjän nimen ja kirjoittaa ruudulle (stdout) Hyvää päivää, Nimi Niminen! niin monta kertaa kuin käyttäjän syöttämässä nimessä on merkkejä.

Kirjallisuutta [1] IEEE standard for binary floating-point arithmetic, 1985. ANSI/IEEE Std 754-1985. [2] 7-Bit coded Character Set, 1991. Standard ECMA 6. WWW: http://www.ecma. ch/ecma1/stand/ecma-006.htm. [3] Addison-Wesley, Reading, MA. The Unicode Standard, Version 4.0, 2003. [4] Alfred V. Aho, Ravi Sethi, ja Jeffrey D. Ullman. Compilers: Principles, Techniques and Tools. Addison-Wesley, Reading, MA, 1988. [5] Andrew W. Appel ja Jens Palsberg. Modern Compiler Implementation in Java. Cambridge University Press, Cambridge, 2 laitos, 2002. [6] John Backus. Can programming be liberated from the von Neumann style? A functional style and its algebra of programs. Communications of the ACM, 21(8), Elokuu 1978. [7] C. J. Burgess. Software quality issues when choosing a programming language. Kirjassa Software Quality Management III Vol. 2, sivua 25 31. Computational Mechanics Publications, 1995. [8] O.-J. Dahl, E. W. Dijkstra, ja C. A. R. Hoare. Structured Programming. Academic Press, Lontoo, 1972. [9] Erich Gamma, Richard Helm, Ralph Johnson, ja John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, Boston, 1995. [10] C. A. R. Hoare. Hints on programming language design. Kirjassa C. A. R. Hoare ja C. B. Jones (toim.), Essays in Computer Science. Prentice-Hall, New York, 1989. [11] C. A. R. Hoare. A hard act to follow. Higher-Order and Symbolic Computation, 13(1 2):71 72, 2000. [12] International Organization for Standardization. Information lechnology Syntactic metalanguage Extended BNF, 1996. ISO/IEC 14977:1996(E). [13] International Organization for Standardization. Programming languages C, 1999. ISO/IEC 9899:1999. [14] Antti-Juhani Kaijanaho ja Benjamin Fallenstein. Totally different structural programming: Programming languages in ZigZag. WWW: http://www.mit. jyu./antkaij/plinzz.pdf, Elokuu 2001. An invited talk presented at the First International ZigZag Conference, part of ACM Hypertext Conference 2001 in Århus, Denmark on August 14, 2001. [15] Richard Kelsey, William Klinger, Jonathan Rees, et al. Revised 5 report on the algorithmic language Scheme. ACM SIGPLAN Notices, 33(9):26 76, Syyskuu 1998. [16] Donald E. Knuth. Backus normal form vs. backus naur form. Communications of the ACM, 7(12), Joulukuu 1962. Letter to the editor. [17] Donald E. Knuth ja Luis Trabb Pardo. The early development of programming languages. Kirjassa J. Belzer, A. G. Holzman, ja A. Kent (toim.), Encyclopedia of Computer Science and Technology, nide 6. Dekker, New York, 1977. Julkaistu myös kirjassa [21]. 87

88 KIRJALLISUUTTA [18] Thomas E. Kurtz. BASIC. ACM SIGPLAN Notices, 13(8):103 118, Elokuu 1978. Preprints, First ACM SIGPLAN History of Programming Languages Conference. [19] Patricia K. Lawlis. Guidelines for choosing a computer language: Support for the visionary organization, Elokuu 1997. [20] John McCarthy. History of LISP. ACM SIGPLAN Notices, 13(8):217 223, Elokuu 1978. Preprints, First ACM SIGPLAN History of Programming Languages Conference. [21] N. Metropolis, J. Howlett, ja Gian-Carlo Rota (toim.). A History of Computing in the Twentieth Century. Academic Press, New York, 1980. [22] Robin Milner. A theory of type polymorphism in programming. Journal of Computer and System Sciences, 17(3):348 375, 1978. [23] Peter Naur et al. Revised report on the algorithmic language ALGOL 60. Communications of the ACM, 6(1):1 17, Tammikuu 1963. [24] John K. Ousterhout. Scripting: Higher-level programming for the 21st century. Computer, 31(3):23 30, Maaliskuu 1998. [25] Alan J. Perlis. Epigrams on programming. ACM SIGPLAN Notices, 17(9), Syyskuu 1982. [26] Simon Peyton Jones (toim.). Haskell 98 Language and Libraries: The Revised Report. Cambridge University Press, Huhtikuu 2003. [27] Simon Peyton Jones. Haskell 98 language and libraries: The revised report. Journal of Functional Programming, 13(1), Tammikuu 2003. [28] Simon L. Peyton Jones. The Implementation of Functional Programming Languages. Prentice-Hall, New York, 1987. [29] Eric S. Raymond. The Art of Unix Programming. Addison-Wesley, Boston, 2003. [30] John C. Reynolds. Theories of Programming Languages. Cambridge University Press, Cambridge, 1998. [31] Guy Lewis Steele, Jr. Debunking the expensive procedure call myth or procedure call implementations considered harmful or, LAMBDA: The ultimate GOTO. Kirjassa James K. Ketchel et al. (toim.), Proceedings of the 1977 annual conference, sivua 153 162. ACM Press, 1977. [32] Christopher Strachey. Fundamental concepts in programming languages. Higher-Order and Symbolic Computation, 13:11 49, 2000. Perustuu Stracheyn vuonna 1967 pitämiin luentoihin. [33] A. van Wijngaarden et al. (toim.). Revised Report on the Algorithmic Language Algol 68. Springer, Berliini, 1976. [34] Larry Wall. Perl, the first postmodern computer language. http://www.wall. org/ larry/pm.html, 1999. A talk given in Linux World Spring 1999.

LIITE A Neloskoneen systeemikutsut (0) Avaa olemassaoleva tiedosto. Parametrit: [SP + 0] sisältää osoitteen, josta löytyy avattavan tiedoston nimen ensimmäinen kirjain (tavu); loput kirjaimet sijaitsevat seuraavissa tavuissa. [SP + 4] sisältää etumerkittömän kokonaisluvun, joka kertoo tiedoston nimen pituuden tavuina. [SP + 8] sisältää etumerkittömän kokonaisluvun, joka kertoo tiedoston käyttötarkoituksen: se on 0, jos tiedostoa vain luetaan, 1, jos tiedostoon vain kirjoitetaan, ja 2, jos tiedostoa luetaan ja siihen kirjoitetaan. Paluutieto: [SP + 0] sisältää etumerkillisen kokonaisluvun. Jos se on negatiivinen, avaaminen epäonnistui; jos se on positiivinen tai nolla, se on tiedoston tunnus, joka annetaan avattua tiedostoa käsitteleville systeemikutsuille merkiksi, että on käsiteltävä juuri tätä tiedostoa. Virhetilanteet: Avaaminen epäonnistuu, jos nimettyä tiedostoa ei ole tai sitä ei voida avata haluttua käyttötarkoitusta varten. (1) Luo uusi tiedosto ja avaa se. Parametrit: [SP + 0] sisältää osoitteen, josta löytyy luotavan tiedoston nimen ensimmäinen kirjain (tavu); loput kirjaimet sijaitsevat seuraavissa tavuissa. [SP + 4] sisältää etumerkittömän kokonaisluvun, joka kertoo tiedoston nimen pituuden tavuina. [SP + 8] sisältää etumerkittömän kokonaisluvun, joka kertoo tiedoston käyttötarkoituksen: se on 1, jos tiedostoon vain kirjoitetaan, ja 2, jos tiedostoa luetaan ja siihen kirjoitetaan. Paluutieto: [SP + 0] sisältää etumerkillisen kokonaisluvun. Jos se on negatiivinen, avaaminen epäonnistui; jos se on positiivinen tai nolla, se on tiedoston tunnus, joka annetaan avattua tiedostoa käsitteleville systeemikutsuille merkiksi, että on käsiteltävä juuri tätä tiedostoa. Virhetilanteet: Luominen epäonnistuu, jos nimetty tiedosto on jo olemassa tai sen luominen epäonnistuu muusta syystä. (2) Sulje avattu tiedosto. 89

90 A. NELOSKONEEN SYSTEEMIKUTSUT Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on saatu jommalta kummalta avaussysteemikutsulta. Paluutieto: [SP + 0] sisältää etumerkillisen kokonaisluvun. Jos se on negatiivinen, sulkeminen epäonnistui; muuten se onnistui. Virhetilanteet: Sulkeminen epäonnistuu, jos kyseinen tiedosto ei ole auki tai jos mahdollisen kirjoituspuskurin tyhjentäminen epäonnistuu tai lukemisessa on tapahtunut virhe. Sulkemista ei kuitenkaan saa yrittää uudestaan, eikä tiedostotunnusta saa tarjota enää tiedostonkäsittelysysteemikutsuille. (3) Lue tiedostosta Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on joko 0 tai saatu jommalta kummalta avaussysteemikutsulta. [SP + 4] sisältää osoitteen, josta alkaa puskuri, johon tiedostoa luetaan. [SP + 4] sisältää etumerkittömän kokonaisuluvun, joka kertoo kyseisen puskurin pituuden tavuina. Paluutieto: [SP + 0] sisältää etumerkittömän kokonaisluvun, joka kertoo, montako tavua puskuriin luettiin. Tämä luku voi olla pienempi kuin puskurin pituus. Jos tämä luku on nolla mutta puskurin koko oli suurempi kuin nolla, tiedosto on luettu loppuun. Virhetilanteet: Lukemisessa tapahtuva virhe ilmenee siten, että tämä systeemikutsu antaa luettujen merkkien määräksi nollan (merkiten tiedoston loppumista) ja myöhempi tiedoston sulkeminen epäonnistuu. Lukeminen epäonnistuu esimerkiksi, jos tiedostoa ei ole avattu lukemista varten. Huomioitavaa: Tunnus 0 on auki lukemista varten valmiiksi ohjelman kätynnistyessä (stdin). (4) Kirjoita tiedostoon Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on joko 1 tai 2 tai saatu jommalta kummalta avaussysteemikutsulta. [SP + 4] sisältää osoitteen, josta alkaa tavujono, jok tiedostoon kirjoitetaan. [SP + 4] sisältää etumerkittömän kokonaisuluvun, joka kertoo kyseisen tavujonon pituuden tavuina. Paluutieto: [SP + 0] sisältää etumerkittömän kokonaisluvun, joka kertoo, montako tavua kirjoitettiin tavujonon alusta alkaen. Tämä luku voi olla pienempi kuin tavujonon. Jos tämä luku on nolla mutta jonon pituus oli suurempi kuin nolla, on tapahtunut kirjoitusvirhe.

A. NELOSKONEEN SYSTEEMIKUTSUT 91 Virhetilanteet: Kirjoittamisessa tapahtuva virhe ilmenee joko vajaana kirjoitusmääränä tai myöhemmin tehtävän tiedoston sulkemisen epäonnistumisena. Huomioitavaa: Tunnukset 1 ja 2 ovat auki kirjoittamista varten valmiiksi ohjelman kätynnistyessä (stdout ja stderr). (5) Muuta luku/kirjoituskohdan sijaintia (seek) Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on saatu jommalta kummalta avaussysteemikutsulta. [SP + 4] sisältää etumerkittömän kokonaisluvun, joka ilmaisee, kuinka monen tavun päähän tiedoston alusta tiedoston luku/kirjoituskohta tulisi siirtää. Paluutieto: Ei paluutietoa. Huomioitavaa: Jos virhetilanne sattuu, luku/kirjoituspään paikka voi siirtyä minne vain tiedostossa. Jos sama tiedosto on samanaikaisesti auki usealla eri tunnuksella, jokaisella niistä on oma luku/kirjoituskohta, joten tämä kutsu vaikuttaa vain siihen tunnukseen, joka annetaan parametrina. (6) Kerro luku/kirjoituskohdan sijainti (tell) Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on saatu jommalta kummalta avaussysteemikutsulta. Paluutieto: [SP + 0] sisältää etumerkittömän kokonaisluvun, joka ilmaisee, kuinka monen tavun päässä tiedoston alusta tiedoston luku/kirjoituskohta on. Huomioitavaa: Jos sama tiedosto on samanaikaisesti auki usealla eri tunnuksella, jokaisella niistä on oma luku/- kirjoituskohta, joten tämä kutsu kertoo vain sen tunnuksen, joka annetaan parametrina, luku/kirjoituskohdan. (7) Jakaudu (fork) Kuvaus: Tämä systeemikutsu tekee kopion ohjelman näkemästä neloskoneesta, minkä jälkeen sekä alkuperäinen että kopio jatkavat suoritusta rinnakkain systeemikutsun jälkeen tulevalla käskyllä. Vertaa Unixin fork(2)- systeemikutsuun. Parametrit: Ei parametreja. Paluutieto: [SP + 0] sisältää etumerkillisen kokonaisluvun, joka on nolla kopiossa ja positiivinen alkuperäisessä koneessa (kopion tunnus). Virhetilanteessa tämä paluutieto on negatiivinen, eikä kopiota ole tehty.

92 A. NELOSKONEEN SYSTEEMIKUTSUT Huomioitavaa: Kopio tehdään datamuistista, nollamuistista ja pinomuistista. Tekstimuisti on molemmille yhteinen. Kopiossa on auki samat tiedostot samoilla tunnuksilla kuin alkuperäisessäkin, mutta jakautumisen jälkeen tehdyt muutokset luku/kirjoituskohdan sijaintiin tai tiedoston sulkeminen eivät välity toiselle. (8) Kloonaudu (clone) Kuvaus: Samanlainen kuin edellinen pienin eroin. Parametrit: Ei parametreja. Paluutieto: [SP + 0] sisältää etumerkillisen kokonaisluvun, joka on nolla kopiossa ja positiivinen alkuperäisessä koneessa (kopion tunnus). Virhetilanteessa tämä paluutieto on negatiivinen, eikä kopiota ole tehtyt. Huomioitavaa: Kopio tehdään vain pinomuistista. Tekstimuisti, datamuisti ja nollamuisti sekä ZL-rekisteri ovat molemmille yhteisiä. Myös aukinaiset tiedostot ovat yhteisiä (uudet avaukset, tiedostojen sulkemiset ja luku/- kirjoituskohdan muutokset näkyvät kummallekin riippumatta siitä, kumpi operaation tekee). (9) Lähetä viesti toiselle rinnalla suoritettavalle koneelle. Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on sen koneen (jakautumissysteemikutsun antama) tunnus, jolle viesti halutaan lähettää. [SP + 4] sisältää osoitteen, josta alkaa lähetettävä viesti tavujonona. [SP + 8] sisältää etumerkittömän kokonaisuluvun, joka kertoo viestin pituuden tavuina. Paluutieto: [SP + 0] sisältää etumerkillisen kokonaisluvun, joka on negatiivinen, jos viestin lähetys epäonnistuu ja muuten nolla. Huomioitavaa: Viestinlähetys on synkronista, jolloin lähettävä kone odottaa, kunnes vastaanottava kone ottaa viestin vastaan. Jos näin ei koskaan käy, lähettävä kone ei koskaan palaa tästä systeemikutsusta. (10) Vastaanota viesti. Parametrit: Ei parametreja. Paluutieto: Vastaanotettu viesti on pinossa alkaen osoitteesta SP + 4; viestin pituus tavuina on muistipaikan [SP + 0] sisältö etumerkittömänä kokonaislukuna. Jos pituus on nolla, vastaanottaminen epäonnistui. Huomioitavaa: Viestinlähetys on synkronista, jolloin vastaanottava kone odottaa, kunnes joku kone lähettää sille jonkin viestin. Jos näin ei koskaan käy, vastaanottava kone ei koskaan palaa tästä systeemikutsusta. Jos kaksi

A. NELOSKONEEN SYSTEEMIKUTSUT 93 tai useampi kone lähettää samalle koneelle viestin yhtä aikaa, niiden vastaanottojärjestys on määrittelemätön. Viestin pituus on aina neljällä jaollinen; jos lähettäjä on lähettänyt muunlaisen viestin, viestin lopussa on yhdestä kolmeen ylimääräistä nollatavua jatkamassa viestin pituutta neljällä jaolliseksi. (11) Sammuta kone. Parametrit: [SP + 0] sisältää ohjelman lopetuskoodin (einegatiivinen etumerkillinen kokonaisluku); 0 tarkoittaa onnistunutta suoritusta. Paluutieto: Systeemikutsu ei palaa. Huomioitavaa: Tämä systeemikutsu sammuttaa vain sen koneen, joka systeemikutsun tekee. Muut rinnalla käynnissä olevat koneet jatkavat toimintaansa normaalisti. (12) Odota rinnakkaisen koneen sammumista. Parametrit: [SP + 0] sisältää positiivisen etumerkillisen kokonaisluvun, joka on sen koneen (jakautumissysteemikutsun antama) tunnus, jonka sammumista odotetaan. Paluutieto: [SP + 0] sisältää sammuneen koneen sammuessaan antaman lopetuskoodin (ei-negatiivinen etumerkillinen kokonaisluku). Virhetilanteessa se on negatiivinen. Huomioitavaa: Koneen sammuttua sen lopetuskoodi pidetään muistissa, kunnnes joku toinen kone ottaa lopetuskoodin vastaan tällä kutsulla. Jos kone ei ole vielä sammunut, tämä systeemikutsu odottaa sen sammumista. Jos konetta ei ole tai sen lopetuskoodia ei ole enää muistissa, palaa systeemikutsu välittömästi paluutietonaan negatiivinen luku. (13) Aika Parametrit: Ei parametreja. Paluutieto: [SP + 0] sisältää millisekuntien lukumäärän laskien ajanhetkestä, jolloin simulaattori käynnistettiin. Huomioitavaa: Kyseinen nolla-ajanhetki on sama kaikilla rinnakkain ajettavilla koneilla mutta se voi muuttua suorituskerrasta toiseen. Tämän systeemikutsun käyttämä kello voi jätättää mutta se ei edistä. Huomaa, että 32-bittinen millisekuntilaskuri kykenee esittämään noin 50 päivän mittaisen ajanjakson; jos se aika ylittyy, laskuri aloittaa taas nollasta.