Oversikt Oversettelse Logging Implementasjon Oppsummering

Like dokumenter
Dagens tema: Formålet. Kodegenerering NB! Introduksjon Modulen Code. Enkle variable Noen enkle setninger Uttrykk

Dagens tema: Formålet. Kodegenerering NB! Introduksjon Modulen Code. Enkle variable Noen enkle setninger Uttrykk

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet (kalt kildekoden): Hva er kompilering?

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Hovedansvarlig. Symbolgenerator. Tregenerator. Litt mer kompliserte setninger med betingelser

Dagens tema. Rask-maskinen. Rasko-kode Raskas-kode. Litt datamaskinhistorie Registre og lagre Instruksjoner

En overikt. Dagens tema. Datamaskinenes historie. Rask-maskinen Litt datamaskinhistorie Registre og lagre Instruksjoner. Rasko-kode.

Dagens tema: Generelt om variable. Kodegenerering. Deklarasjon av array er. Versjonskontroll. Oppslag i array er

Dagens tema: Kodegenerering. Redigeringsverktøy. Versjonskontroll. Array-er Funksjoner og kall Hovedprogrammet Noen siste gode råd.

Dagens tema. Datamaskinenes historie. De første moderne datamaskiner. Løsning. Menneskene har alltid prøvd å lage maskiner for å løse sine problemer.

Dagens tema: Maskinkode. Litt datamaskinhistorie Hva er maskin- og assemblerkode? x86-prosessoren Programkode og variabler

Oversikt Kompilering Syntaksanalyse Java Feilsjekking Oppsummering

Dagens tema: Resten av det dere trenger til del 1

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Hva skal gjøres? Dagens tema: Hva gjør en kompilator? Forenkling

Dagens tema: 12 gode råd for en kompilatorskriver. Prosjektet. Modifikasjon av grammatikken. Utifra dette RusC programmet:

Dagens tema: 12 gode råd for en kompilatorskriver. Prosjektet. Koblingen mellom grammatikken og klasser. Utifra dette RusC-programmet:

Dagens tema: Resten av det dere trenger til del 1

Dagens tema: Prosjektet. Hva er en god feilmelding? Melding med mening. Ubrukelig. Hvor på linjen? Noe bedre. Enda bedre

2 Parser. 1 Skanner. 4 Kodegenerator. 3 Sjekker. Oversikt Datamaskinhistorie x86 Kodegenerering Setninger Uttrykk.

Dagens tema: Mer av det dere trenger til del 1

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

INF2100. Oppgaver 23. og 24. september 2010

INF2100. Oppgaver uke 40 og

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

Oversikt Deklarasjoner Typesjekk Programmering Datamaskinhistorie x86 Kodegenerering

INF2100. Oppgaver 6. og 11. oktober 2011 C 100 X 10

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java

Dagens tema: Mer av det dere trenger til del 1

INF2100. Oppgave 1. Oppgave 2 4. Løsningsforslag til oppgaver uke 40 og Se figur 1 på neste side.

Prosjektet. Dagens tema: Moduler i prosjektet error log chargenerator scanner. Enum klasser i Java. Programmeringsverktøy Emacs Eclipse

Dagens tema: Hva skal gjøres? Hva gjør en kompilator? Hva gjør en kompilator?

INF 1010, vår 2005 Løsningsforslag uke 11

INF2100. Oppgave 1, 2 og 3. Løsningsforslag til oppgaver 23. og 24. september Her er det mange mulige løsninger her er én: import java.io.

Hvordan skrive Flok og Flass kode? I mange tilfelle er det svært enkelt:

INF5110 Obligatorisk Oppgave 2 del 2. Andreas Svendsen SINTEF. 23. April Oversikt

Dagens tema: Sjekking

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

Velkommen til INF2100

Oppsummering Assemblerkode Hopp Multiplikasjon Kode og data Array Oppsummering

Dagens tema: 12 gode råd for en kompilatorskriver

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

Del 3: Evaluere uttrykk

Eivind Gard Lund. 24. Mars 2009 Foilene bygger på 2009 utgaven av Andreas Svendsen

UNIVERSITETET I OSLO

INF 1000 høsten 2011 Uke september

INF Noen oppgaver til kap. 8

INF1010 våren 2017 Onsdag 25. januar. Litt om unntak i Java

INF april, 2013 Kap. 8 Noen oppgaver som er meget relevante for Oblig 2

Dagens tema. LC-2 LC-2 er en «ekstrem-risc»; den har 16 instruksjoner og 3 adresseringsmåter.

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Oppgaver til kodegenerering etc. INF-5110, 16. mai, 2014

Bakgrunnen for INF2100. Velkommen til INF2100. Prosjektet. Hva gjør en kompilator?

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

Dagens tema: Semantisk sjekking. Maskinkode. Hvordan finne deklarasjoner? Hvordan programmere sjekking av riktig navnebruk?

Velkommen til INF2100. Bakgrunnen for INF2100. Hva gjør en kompilator? Prosjektet. Jeg er Dag Langmyhr

INF2100. Oppgaver 26. september til 1. oktober 2007

INF Noen oppgaver til kap. 8

2 Om statiske variable/konstanter og statiske metoder.

Velkommen til INF2100

Velkommen til INF2100

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Diverse eksamensgaver

Kodegenerering del 3: Tilleggsnotat fra AHU Samt litt om class-filer og byte-kode INF5110 V2007. Stein Krogdahl, Ifi UiO

INF april, 2014 Stein Krogdahl Ifi, UiO. Svar på oppgaver til kap. 8

Del 1 En oversikt over C-programmering

Velkommen til INF2100

IN2030. Oppgave 1. Løsningsforslag. Uke (Disse filene finnes også i mappen ~inf2100/e/e2/.)

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

En oppsummering (og litt som står igjen)

IN1010 våren januar. Objektorientering i Java

Tema for siste forelesning:

Pensumoversikt - kodegenerering. Kap. 8 del 1 kodegenerering INF5110 v2006. Hvordan er instruksjonene i en virkelig CPU? Arne Maus, Ifi UiO

INF april, 2015 Stein Krogdahl Ifi, UiO. Svar på oppgaver til kap. 8. Ble lagt ut 24. april

INF1010 våren 2019 Onsdag 30. januar. Mer om unntak i Java (med litt repetisjon av I/O først)

Introduksjon til DARK assembly

INF-5110 Oppgaver kodegenerering etc. INF-5110, vår 2011

Hvordan en prosessor arbeider, del 1

Den siste dagen. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Veien videre... Eksamen

Oblig 4Hybelhus litt mer tips enn i oppgaven

Syntaksanalyse. Dagens tema: Språkdiagrammene Jernbanediagrammene er et ypperlig utgangspunkt for å analysere et program: INF2100 INF2100 INF2100

Dagens tema: Kodegenerering. Versjonskontroll. Variabler, spesielt vektorer Funksjoner, kall og parametre Noen siste gode råd.

Forkurs INF1010. Dag 3. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 15.

Fra Python til Java, del 2

Repetisjon. INF gruppe 13

Oppbygningen av en datamaskin Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Programmeringsspråket C

Dagens tema: Sjekking (obligatorisk oppgave 3)

Oppgaver til kodegenerering etc. INF-5110, 12. mai, 2015

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Kapittel 1 En oversikt over C-språket

INF1000: Forelesning 4. Mer om arrayer Metoder

Transkript:

Dagens tema Dagens tema: Kodegenerering Introduksjon Modulen Code Enkle variable Noen enkle setninger Uttrykk Litt mer kompliserte setninger med betingelser (Alt unntatt program, funksjoner og array-er.)

Prosjektoversikt Del-0 Del-1 Del-2 f.rusc Rusc f.rask Char- Generator Scanner Syntax Code Error Log f.log

Formålet Formålet Formålet med kodegenereringen er å lage Rasko-kode som Rask-maskinen kan utføre: Inndata er trerepresentasjonen av RusC-programmet laget i del 1. Utdata er en fil med Rasko-kode.

Et eksempel Anta at vi har RusC-koden putchar(? ); Disse Rask-instruksjonene gjør dette: SET R11,63 CALL 9993 Det finnes mange mulige kodebiter som gjør det samme. I kompendiet står angitt ganske nøyaktig hvilke som skal brukes. NB! Det er viktigere at koden er riktig enn at den er rask!

Et eksempel Rask-maskinen Minne: Inneholder 10 000 celler som kan inneholde enten data eller instruksjoner. 33 registre: R 0 inneholder alltid 0. R 1 R 31 inneholder data. PC gir adressen til neste instruksjon.

Instruksjonene Instruksjonene Nr Navn Operasjon 1 LOAD RA, RB, C RA Mem[RB+C] 2 SET RA, RB, C RA RB+C 3 STORE RA, RB, C Mem[RB+C] RA 4 ADD RA, RB, RC RA RB+RC 5 SUB RA, RB, RC RA RB RC 6 MUL RA, RB, RC RA RB RC 7 DIV RA, RB, RC RA RB/RC Nr Navn Operasjon 8 EQ RA, RB, RC RA 1 hvis RB=RC, ellers 0 9 NEQ RA, RB, RC RA 1 hvis RB RC, ellers 0 10 LESS RA, RB, RC RA 1 hvis RB<RC, ellers 0 11 LESSEQ RA, RB, RC RA 1 hvis RB RC, ellers 0 12 GTR RA, RB, RC RA 1 hvis RB>RC, ellers 0 13 GTREQ RA, RB, RC RA 1 hvis RB RC, ellers 0 14 JUMPEQ RA, RB, C Hvis RA=RB, PC C 15 JUMPNEQ RA, RB, C Hvis RA RB, PC C 16 CALL RA, RB, C R31 PC og PC C 17 RET PC R31

Instruksjonene RusC-programmet int pot2 (int x) { int p2; p2 = 1; while (2*p2 <= x) { p2 = 2*p2; return p2; int x; int main () { int v; v = getint(); x = pot2(v); putint(x); putchar(10);... skal bli Rask-koden #! /local/bin/rask 1600000000000035 211000000000000 1600000000009990 0 0 0 331000000000003 303000000000004 311000000000005 201000000000001 30 201000000000002 203010000000000 101000000000006 60 203010000000000 101000000000005 1101030000000001 1 201000000000002 203010000000000 101000000000006 60 301000000000006 1400000000000012 101000000000006 1 103000000000004 131000000000003 1700000000000000 0 0 0 0 331000000000032 303000000000033 1600000000009992 301000000000034 1 1600000000000007 301000000000031 111000000000031 1 211000000000010 1600000000009993 103000000000033 1 1700000000000000

Opsjonen «logc» Genererte instruksjoner Til hjelp under uttesting finnes opsjonen logc som lar kompilatoren fortelle hvilken kode den lager: Code 0: 1600000000000000 CALL 0 0 0 # main(); Code 1: 211000000000000 SET 11 0 0 # (0) Code 2: 1600000000009990 CALL 0 0 9990 # exit Code 3: RES 1 # Return address in pot2 Code 4: RES 1 # Refuge for R3 in pot2 Code 5: RES 1 # int x Code 6: RES 1 # int p2 Code 7: 331000000000003 STORE 31 0 3 # Save return address Code 8: 303000000000004 STORE 3 0 4 # Save R3 Code 9: 311000000000005 STORE 11 0 5 # Save parameter x Code 10: 201000000000001 SET 1 0 1 # R1 = 1 Code 11: 301000000000006 STORE 1 0 6 # p2 = Code 12: 201000000000002 SET 1 0 2 # R1 = 2 Code 13: 203010000000000 SET 3 1 0 # Save operand in R3 Code 14: 101000000000006 LOAD 1 0 6 # R1 = p2 Code 15: 601030000000001 MUL 1 3 1 # * Code 16: 203010000000000 SET 3 1 0 # Save operand in R3 Code 17: 101000000000005 LOAD 1 0 5 # R1 = x Code 18: 1101030000000001 LESSEQ 1 3 1 # <= Code 19: 1401000000000000 JUMPEQ 1 0 0 # Exit while-loop when test is false

Opsjonen «logc» Code 20: 201000000000002 SET 1 0 2 # R1 = 2 Code 21: 203010000000000 SET 3 1 0 # Save operand in R3 Code 22: 101000000000006 LOAD 1 0 6 # R1 = p2 Code 23: 601030000000001 MUL 1 3 1 # * Code 24: 301000000000006 STORE 1 0 6 # p2 = Code 25: 1400000000000012 JUMPEQ 0 0 12 # Repeat while-loop ---> 19: 1401000000000026 26 # Update break address Code 26: 101000000000006 LOAD 1 0 6 # R1 = p2 Code 27: 1400000000000000 JUMPEQ 0 0 0 # return ---> 27: 1400000000000028 28 # Update address of return jump Code 28: 103000000000004 LOAD 3 0 4 # Restore R3 Code 29: 131000000000003 LOAD 31 0 3 # Restore return address Code 30: 1700000000000000 RET 0 0 0 # Return from pot2 Code 31: RES 1 # int x Code 32: RES 1 # Return address in main Code 33: RES 1 # Refuge for R3 in main Code 34: RES 1 # int v Code 35: 331000000000032 STORE 31 0 32 # Save return address Code 36: 303000000000033 STORE 3 0 33 # Save R3 Code 37: 1600000000009992 CALL 0 0 9992 # Call getint(...)

Opsjonen «logc» Code 38: 301000000000034 STORE 1 0 34 # v = Code 39: 111000000000034 LOAD 11 0 34 # R11 = v Code 40: 1600000000000007 CALL 0 0 7 # Call pot2(...) Code 41: 301000000000031 STORE 1 0 31 # x = Code 42: 111000000000031 LOAD 11 0 31 # R11 = x Code 43: 1600000000009994 CALL 0 0 9994 # Call putint(...) Code 44: 211000000000010 SET 11 0 10 # R11 = 10 Code 45: 1600000000009993 CALL 0 0 9993 # Call putchar(...) Code 46: 103000000000033 LOAD 3 0 33 # Restore R3 Code 47: 131000000000032 LOAD 31 0 32 # Restore return address Code 48: 1700000000000000 RET 0 0 0 # Return from main ---> 0: 1600000000000035 35 # Fix call to main() Å implementere denne opsjonen er en del av den obligatoriske oppgaven.

Metoden gencode Hvordan implementere kodegenerering Det beste er å følge samme opplegg som for å skrive ut programkoden i del 1: Kodegenerering Legg en metode gencode inn i alle klasser som representerer en del av RusC-programmet.

Metoden gencode class WhileStatm extends Statement { Expression test; StatmList body; public static WhileStatm parse(decllist decls) {. public void gencode() {. public void printtree() {.

Modulen Code Modulen Code Modulen Code tar seg av kodegenereringen; all koden lagres først i vektoren mem: package no.uio.ifi.rusc.code; import java.io.*; import no.uio.ifi.rusc.error.error; import no.uio.ifi.rusc.log.log; import no.uio.ifi.rusc.rusc.rusc; public class Code { public static final int codesize = 10000; public static int curaddr = 0; private static long mem[]; public static void init() { //-- Må endres i del 2:.

Modulen Code Metoden finish skriver ut den ferdige Rasko-kodefilen: public static void finish() { String codename = Rusc.sourceName; if (codename == null) return; if (codename.endswith(".rusc")) codename = codename.substring(0,codename.length()-5); codename += ".rask"; PrintWriter f = null; try { f = new PrintWriter(codeName); catch (FileNotFoundException e) { Error.error("Cannot create code file " + codename + "!"); f. println("#! /local/bin/rask"); f.println(); for (int ix = 0; ix < curaddr; ++ix) { f.print(mem[ix]); if (ix%5 == 4) f.println(); else f.print(" "); f.println(); f.close();

Modulen Code De enkelte instruksjonene lagres med geninstr: /** * Puts an instruction into Rask s memory. * * @param instrname The instruction s name (for the log file) * @param instrno The instruction s code number * @param op1 Instruction operand #1 * @param op2 Instruction operand #2 * @param op3 Instruction operand #3 * @param comment A comment to add to the log file * @return The memory address of the generated instructio */ private static int geninstr(string instrname, int instrno, int op1, int op2, int op3, String comment) { if (curaddr >= codesize-10) Error.error("Memory overflow! More than " + (codesize-10) + " instructions/data words generated!"); Log.noteCode(curAddr, instrname, instrno, op1, op2, op3, comment); mem[curaddr++] = instrno*100000000000000l + op1*1000000000000l + op2*10000000000l + op3; return curaddr-1;

Modulen Code Så finnes det en metode for hver instruksjon: public static int genset(int op1, int op2, int op3, String comment) { return geninstr("set", 2, op1, op2, op3, comment); public static int genret(int op1, int op2, int op3, String comment) { return geninstr("ret", 17, op1, op2, op3, comment);

Variable Enkle variable Det må settes av plass i minnet til alle enkle 1 variable. Viktig! Data og instruksjoner ligger i det samme minnet. Datamaskinen Rask vet ikke hva som er hva det må vi som genererer kode, passe på! 1 Array-er er tema neste uke.

Variable Reservasjon av variable løses med en metode i Code: public class Code { public static final int codesize = 10000; public static int curaddr = 0; private static long mem[]; public static int resmem(int nwords, String comment) { if (curaddr+nwords > codesize-10) Error.error("Memory overflow! More than " + (codesize-10) + " instructions/data words generated!");. Log.noteRes(curAddr, nwords, comment); curaddr += nwords; return curaddr-nwords;

Å oversette setninger Setninger I kompendiet finner vi kodeskjemaer for alle setningene. NB! Disse kodeskjemaene skal brukes, selv om de ikke gir optimal kode! Assignment v = e Beregn e, svar i R 1 STORE R1,R0,Adr( v )

Registre Registerbruk For å holde oversikt skal registrene brukes slik: R 0 Alltid 0 (gitt av Rask) R 1 Hovedregister for beregning av uttrykk R 2 Hjelperegister ved vektoraksess R 3 Hjelperegister ved beregning av uttrykk R 11 Parameter 1 ved funksjonskall R 12 Parameter 2 ved funksjonskall R 13 Parameter 3 ved funksjonskall R 14 Parameter 4 ved funksjonskall R 31 Returadresse ved funksjonskall (gitt av Rask)

Et eksempel assign-statm assignment ; assignment variable = expression Kodegenereringsmetoden for AssignStatm blir: class AssignStatm extends Statement { private Assignment assignment; public void gencode() { assignment.gencode();.

Et eksempel class Assignment extends SyntaxUnit { Variable lhs; /* "Left hand side" */ Expression rhs; /* "Right hand side" */ public void gencode() { rhs.gencode(); if ( er et array-element ) {. else { Code.genStore(1, 0, lhs.declref.memaddr, lhs.declref.name+" = ");.

Uttrykk Uttrykk Hvordan lager vi kode for et uttrykk som 4 * a - 17? Første operand Det er ganske enkelt å lage kode som legger en variabel i R 1 -registeret: v LOAD R1,R0,Adr( v )

Uttrykk Det er nesten like enkelt for konstanter (tall eller tegn); vi må bare spesialbehandle negative tall. (Hvorfor det?) n SET R1,R0, n - n SET SUB R1,R0, n R1,R0,R1

Uttrykk Resten av uttrykket Resten av uttrykket består av 0 eller flere par av operator,konstant/variabel som vi kan ta etter tur. Slik oversetter vi +: e 1 + e 2 Beregn e 1, svar i R 1 SET R3,R1,0 Beregn e 2, svar i R 1 ADD R1,R3,R1 Ved at alle operander er innom R 1 blir det enklere å skrive kodegenereringen (men koden blir ikke fullt så rask).

Uttrykk class Expression extends SyntaxUnit { ExprElement firstelem = null; public void gencode() { firstelem.gencode(); ExprElement e = firstelem.nextelem; while (e!= null) { Code.genSet(3, 1, 0, "Save operand in R3"); e.nextelem.gencode(); e.gencode(); e = e.nextelem.nextelem;.

While-setningen Setninger Noen setninger er litt mer kompliserte å generere kode for. While-setningen while ( e ) { S Lw: Beregn e, svar i R 1 JUMPEQ R1,R0,Lx S JUMPEQ R0,R0,Lw Lx:

Hopp RusC-koden while (a < 10) { a = a + 1; skal generere denne koden: Code 10: 101000000000005 LOAD 1 0 5 Code 11: 203010000000000 SET 3 1 0 Code 12: 201000000000010 SET 1 0 10 Code 13: 1001030000000001 LESS 1 3 1 Code 14: 1401000000000021 JUMPEQ 1 0 21 Code 15: 101000000000005 LOAD 1 0 5 Code 16: 203010000000000 SET 3 1 0 Code 17: 201000000000001 SET 1 0 1 Code 18: 401030000000001 ADD 1 3 1 Code 19: 301000000000005 STORE 1 0 5 Code 20: 1400000000000010 JUMPEQ 0 0 10

Hopp Hoppadresser Koden inneholder to hopp: Code 10: 101000000000005 LOAD 1 0 5 Code 11: 203010000000000 SET 3 1 0 Code 12: 201000000000010 SET 1 0 10 Code 13: 1001030000000001 LESS 1 3 1 Code 14: 1401000000000021 JUMPEQ 1 0 21 Code 15: 101000000000005 LOAD 1 0 5 Code 16: 203010000000000 SET 3 1 0 Code 17: 201000000000001 SET 1 0 1 Code 18: 401030000000001 ADD 1 3 1 Code 19: 301000000000005 STORE 1 0 5 Code 20: 1400000000000010 JUMPEQ 0 0 10 Hopp til kjent adresse Den siste hoppet er greit nok: Bare husk adressen da man begynte å lage kode for setningen.

Hopp Hopp til ukjent adresse Hva med det første hoppet? Hvor skal vi hoppe? Løsningen er: 1. Generér en hoppinstruksjon til adresse 0. 2. Når vi en stund senere vet den riktige adressen, kan vi sette inn denne i stedet.

Oppsummering Hele koden class WhileStatm extends Statement { Expression test; StatmList body; public void gencode() { int startaddr = Code.curAddr; test.gencode(); int jumpaddr = Code.genJumpEq(1, 0, 0, "Exit while-loop when test is false"); body.gencode(); Code.genJumpEq(0, 0, startaddr, "Repeat while-loop");. Code.updateInstr(jumpAddr, Code.curAddr, "Update break address");

Hva vi har lært I dag kodegenerering generelt kodegenerering for uttrykk tilordning while-setninger Neste uke Kodegenerering for array-er funksjoner og funksjonskall hovedprogrammet