Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Like dokumenter
Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

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

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

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Tema for siste forelesning:

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

Tema for siste forelesning:

Dagens tema: Sjekking

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

Tema for siste forelesning:

En oppsummering (og litt som står igjen)

Notater: INF2270 Assembler

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

INF2100. Oppgaver uke 40 og

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

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

C og kompilatoren hans. Kompendium for INF2100

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

Pensum Hovedtanker Selvmodifiserende Overflyt Veien videre Eksamen. Oppsummering

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

Dagens tema: Sjekking (obligatorisk oppgave 3)

Dagens tema Programmering av x86 Flytting av data Endring av størrelse

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Dagens tema: 12 gode råd for en kompilatorskriver

Dagens tema. Minnestrukturen Grovt sett ser minnet for hver process slik ut: Flytting av data. Programmering av x86

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

En oppsummering. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Eksamen. Programmeringsoppgaver Flervalgsoppgaver

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; }

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

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.

Oversikt. INF1000 Uke 2. Repetisjon - Program. Repetisjon - Introduksjon

Dagens tema. Representasjon av mantissen En desimalbrøk: 1 1, INF1070 INF1070 INF1070 INF1070

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

UNIVERSITETET I OSLO

Løsningsforslag til eksamen i INF2270

UNIVERSITETET I OSLO

AlboC og kompilatoren hans. Kompendium for INF2100

MAT-INF 1100: Obligatorisk oppgave 1

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

INF Noen oppgaver til kap. 8

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

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

MAT-INF 1100: Obligatorisk oppgave 1

Hjemmeeksamen 2 i INF3110/4110

Del 4 Noen spesielle C-elementer

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

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

Dagens tema: INF2100. Syntaksanalyse. Hva annet gjør en kompilator? Sjekking av navnebruk. Testutskrifter

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

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

UNIVERSITETET I OSLO

Dagens tema. Er maskinen big endian? Denne funksjonen tester det: INF1070 INF1070 INF1070 INF1070

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Nybegynnerkurs i C. Øyvind Grønnesby. 14. oktober Introduksjon Typer Operatorer Kontrollstrukturer Pekere Makroer Lenker

Transkript:

Dagens tema Dagens tema: Kodegenerering Introduksjon Enkle variable Uttrykk Tilordning Litt mer kompliserte setninger med betingelser (Alt om kodegenerering unntatt funksjoner.)

Prosjektoversikt Del-0 Del-1 Del-2 f.cflat cflat f.s types chargenerator scanner syntax code error log f.log

Det endelige målet Formålet Vårt oppdrag er å lage en kompilator: Inndata er trerepresentasjonen av C -programmet laget i del 1. Utdata er en fil med x86 assemblerkode.

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Hvordan ser datamaskinen vår ut? Datamaskinen vår Minnet inneholder tre former for data: Data inneholder globale variabler. Stakken inneholder parametre og lokale variabler. Koden er programmet (som tall).

Hvordan ser datamaskinen vår ut? movl v 1, v 2 Flytt v 1 til v 2. cdq Omform 32-bits %EAX til 64-bits %EDX:%EAX. leal v 1, v 2 Flytt adressen til v 1 til v 2. pushl v Legg v på stakken. popl v Fjern toppen av stakken og legg verdien i v. addl v 1, v 2 Addér v 1 til v 2. subl v 1, v 2 Subtraher v 1 fra v 2. imull v 1, v 2 Multipliser v 1 med v 2. idivl v Del %EDX:%EAX med v ; svar i %EAX. call lab Kall funksjonen i lab. ret Returner fra funksjonen. cmpl v 1, v 2 Sammenligning v 1 og v 2. jmp lab Hopp til lab. sete v Sett v =1 om =, ellers v =0. setne v Sett v =1 om, ellers v =0. setl v Sett v =1 om <, ellers v =0. setle v Sett v =1 om, ellers v =0. setg v Sett v =1 om >, ellers v =0. setge v Sett v =1 om, ellers v =0.

Hvordan ser datamaskinen vår ut? faddp Adder to flyttall. fdivp Divider ett flyttall på et annet. fildl v Legg heltall i v på stakken som flyttall. fistpl v Lagre flyttall som int i v. fldl fv Legg flyttall på stakken. fldz Legg 0,0 på stakken. fmulp Multipliser to flyttall. fstpl fv Lagre flyttall som double i fv. fstps fv Lagre flyttall som float i fv. fsubp Subtraher ett flyttall fra et annet.

Et eksempel Anta at vi har C -koden v = 1 + 2; Disse x86-instruksjonene gjør dette: movl $1,%eax # %EAX=1 %ECX=? stack=... pushl %eax # %EAX=1 %ECX=? stack=... 1 movl $2,%eax # %EAX=2 %ECX=? stack=... 1 movl %eax,%ecx # %EAX=2 %ECX=2 stack=... 1 popl %eax # %EAX=1 %ECX=2 stack=... addl %ecx,%eax # %EAX=3 %ECX=2 stack=... movl %eax,v # v = 3 Husk! Det finnes mange mulige kodebiter som gjør det samme. I kompendiet står angitt nøyaktig hvilke som skal brukes.

Metoden gencode Hvordan implementere kodegenerering Det beste er å følge samme opplegg som for å sjekke programkoden: Kodegenerering Legg en metode gencode inn i alle klasser som representerer en del av C -programmet (dvs er subklasse av SyntaxUnit).

Metoden gencode class WhileStatm extends Statement { Expression test = new Expression(); StatmList body = new StatmList(); @Override void check(decllist curdecls) {. @Override void gencode(funcdecl curfunc) {. @Override void parse() {. @Override void printtree() {.

Konvensjoner Konvensjoner Kodegenerering blir mye enklere om vi setter opp noen fornuftige konvensjoner: Alle int-beregninger skal ende opp i %EAX. Alle double-beregninger skal legges på flyttallsstakken. %ECX og %EDX er hjelperegistre. Hovedstakken (aksessert via %ESP) er til mellomresultater av int-verdier funksjonskall Flyttallsstakken er til mellomresultater av double-verdier (neste uke)

Hva slags variabler har vi? Variabler Det finnes fem sorter variabler i C : Enkle Array-er Globale Lokale (De blå tar vi neste uke.) Parametre De kan være int eller double. De kan forekomme i tre ulike situasjoner: Deklarasjon int v; Tilordning v = 1; Bruk if (v>0)...

Generering av globale variable abstract class Declaration extends SyntaxUnit { String name, assemblername; Type type; boolean visible = false; Declaration nextdecl = null;. abstract class VarDecl extends Declaration {. class GlobalSimpleVarDecl extends VarDecl { GlobalSimpleVarDecl(String n) { super(n); assemblername = (Cflat.underscoredGlobals()? "_" : "") + n; @Override void gencode(funcdecl curfunc) { Code.genVar(assemblerName, true, declsize(), type.typename()+" "+name+";");.

Generering av globale variable Metoden Code.genVar vil sette av plass til globale variabler: public static void genvar(string name, boolean global, int nbytes, String comment) { if (! generatingdata) { codefile.println(".data"); generatingdata = true; if (global) codefile.println(".globl " + name); printlabel(name, false); codefile.printf(".fill %-24d", nbytes); if (comment.length() > 0) { codefile.print("# " + comment); codefile.println();

Tilordning Setninger I kompendiet finner vi kodeskjemaer for alle setningene. Assignment iv = ie ia [ ie 1 ] = ie 2 ; Beregn ie med svar i %EAX movl %eax, iv Beregn ie 1 med svar i %EAX pushl %eax Beregn ie 2 med svar i %EAX leal ia,%edx popl %ecx movl %eax,(%edx,%ecx,4)

Tilordning Assignment av flyttall fv = fe Beregn fe med svar på f-stakken fstpl fv Noen ganger må vi konvertere fra int til float: fv = ie ; Beregn ie med svar i %EAX movl %eax,.tmp fildl.tmp fstpl fv (Legg merke til hjelpevariabelen.tmp den må alltid være der.)

Tilordning Et forslag til implementering: class AssignStatm extends Statement { Assignment assignment = new Assignment(); @Override void gencode(funcdecl curfunc) { assignment.gencode(curfunc);. class Assignment extends SyntaxUnit { Variable lhs = new Variable(); /* "Left hand side" */ Expression rhs = new Expression(); /* "Right hand side" */ @Override void gencode(funcdecl curfunc) { if ( det dreier seg om et array-element ) { // To be written... else { rhs.gencode(curfunc); lhs.declref.genstore(rhs.valtype);.

Tilordning Hint Alle VarDecl bør ha en genstore- og genstorearray-metode for å lage kode for tilordning til seg selv; de kan se slik ut: abstract class VarDecl extends Declaration { VarDecl(String n) { super(n); void genstore(type valtype) { if (type==types.doubletype && valtype==types.doubletype) { Code.genInstr("", "fstpl", assemblername, name+" ="); else if (type==types.doubletype && valtype==types.inttype) { Code.genInstr("", "movl", "%eax,"+code.tmplabel, ""); Code.genInstr("", "fildl", Code.tmpLabel, " (double)"); Code.genInstr("", "fstpl", assemblername, name+" ="); else if (type==types.inttype && valtype==types.doubletype) { Code.genInstr("", "fistpl", assemblername, name+" = (int)"); else if (type==types.inttype && valtype==types.inttype) { Code.genInstr("", "movl", "%eax,"+assemblername, name+" ="); else { Error.panic("Declaration.genStore");

Hvordan lagres uttrykk? Uttrykk expression Hvordan lager vi kode for et uttrykk som 4 * a - 17? factor term term opr - factor operand factor opr * operand operand number 4 variable a number 17

Operander Operander Det er ganske enkelt å lage kode som legger en global enkel int-variabel i %EAX-registeret eller en double-variabel på flyttallsstakken: iv movl iv,%eax fv fldl fv Det er like enkelt for int-konstanter (tall eller tegn). n movl $ n,%eax ($-tegnet angir at det er snakk om en tallkonstant.)

Operatorer Aritmetisk int-operatorer ie 1 + ie 2 Beregn ie 1 med svar i %EAX pushl %eax Beregn ie 2 med svar i %EAX movl %eax,%ecx popl %eax addl %ecx,%eax Ved at alle int-operander er innom %EAX blir det enklere å skrive kodegenereringen. Divisjon og sammenligninger er litt vanskeligere; se tabellene i kompendiet. Hvorfor må ie 1 legges på stakken? double-operatorene fordrer helt annen kode.

Kodegenering While-setningen med int-test while ( ie ) { S.Ln 1 :.Ln 2 : Beregn ie med svar i %EAX cmpl $0,%eax je.ln 2 S jmp.ln 1

Kodegenering While-setningen med double-test while ( fe ) { S.Ln 1 :.Ln 2 : Beregn fe med svar på f-stak fstps.tmp cmpl $0,.tmp je.ln 2 S jmp.ln 1

Kodegenering Siden de to variantene er like med unntak av kode for testen, er det nyttig med abstract public class Type { abstract public int size(); abstract public String typename(); public void genjumpifzero(string jumplabel) { public class Types { public static BasicType doubletype, inttype; public static void init() { doubletype = new BasicType() { ; @Override public void genjumpifzero(string jumplabel) { Code.genInstr("", "fstps", Code.tmpLabel, ""); Code.genInstr("", "cmpl", "$0,"+Code.tmpLabel, ""); Code.genInstr("", "je", jumplabel, "");

Navnelapper Lokale navnelapper Når vi skal lage slike hopp, trenger vi stadig nye navnelapper. Dette kan vi få fra Code-modulen: private static int numlabels = 0; public static String getlocallabel() { return String.format(".L%04d", ++numlabels);

Komplett kode Hele koden for WhileStatm class WhileStatm extends Statement { Expression test = new Expression(); StatmList body = new StatmList(); @Override void gencode(funcdecl curfunc) { String testlabel = Code.getLocalLabel(), endlabel = Code.getLocalLabel(); Code.genInstr(testLabel, "", "", "Start while-statement"); test.gencode(curfunc); test.valtype.genjumpifzero(endlabel); body.gencode(curfunc); Code.genInstr("", "jmp", testlabel, ""); Code.genInstr(endLabel, "", "", "End while-statement");

Et eksempel while (a < 10) { a = a + 1;.L0001: # Start while-statement movl a,%eax # a pushl %eax movl $10,%eax # 10 popl %ecx cmpl %eax,%ecx movl $0,%eax setl %al # Test < cmpl $0,%eax je.l0002 movl a,%eax # a pushl %eax movl $1,%eax # 1 movl %eax,%ecx popl %eax addl %ecx,%eax # Compute + movl %eax,a # a = jmp.l0001.l0002: # End while-statement