Løsningsforslag til ukeoppgaver uken 5. til 10. september 2007 Oppgave 1 --------- Funksjonen `init´ bygger opp en tabell `f´ der f[0] = f[1] = 1 og de andre cellene [fx] er f[x-1]+f[x-2]. (Dette er de såkalt Fibonacci-tallene.) Hovedfunksjonen `main´ kaller først `init´. Så ber den om tall fra brukeren og skriver ut tilsvarende element fra array-en. Programmet stopper når brukeren oppgir et negativ tall. Oppgave 2 --------- Oppdateringen av `i´ i `init´ er galt plassert og er dermed gal (1 for stor) i tilordningen til `f[i]´. Resultatet er (i tillegg til at tabellen blir gal) at returadressen til `init´ i celle 104 blir overskrevet med et kjempetall. Følgelig går returen helt galt av sted. Oppgave 3 --------- Her er det mange mulige løsninger. Dette er bare ett: start: JUMP main # Programmet starter i `main´. f: RES 101 # Array-en f. # func init () # ------------ init: SET R21,1 # «Konstantene» 1 SET R22,100 # og 100. STORE R21,R0,f # f[0] = 1; STORE R21,R21,f # f[1] = 1; SET R1,2 # i = 2; i_loop: LESSEQ R23,R1,R22 # while ( JUMPEQ R23,R0,i_exit # i <= 100) { SUB R23,R1,R21 # i1 = i-1; SUB R24,R23,R21 # i2 = i1-1; LOAD R25,R23,f # f[i1] LOAD R26,R24,f # f[i2]; ADD R25,R25,R26 # + STORE R25,R1,f # f[i] = ADD R1,R1,R21 # i = i+1; JUMP i_loop # } i_exit: RET # func main () # ------------ main: CALL init # init(); # while (1) { m_loop: SET R11,'?' # '?' CALL putchar # putchar( ); CALL getint # i = getint(); LESS R4,R1,R0 # i < 0 JUMPEQ R4,R0,m_cont # if ( ) { SET R11,0 # 0 CALL exit # exit( ); # } m_cont: LOAD R11,R1,f # res = f[v]; CALL putint # putint(res); SET R11,10 # LF CALL putchar # putchar( ); JUMP m_loop # } Verdt å merke seg er: 1. Et program starter alltid i adresse 0, så aller først må vi legge et hopp til `main´. (Referanser forover er lov i Raskas selv om det finnes i RusC.) 2. Siden vi skriver all koden selv, kan vi egentlig vedta akkurat de konvensjoner vi vil når det gjelder registerbruk. Jeg har valgt å holde fast på at parametrene skal i R11-R14 og ellers brukt de øvrige etter ønske. Oppgave 4 --------- I linje 3: nameToken skal være `init´ (ikke `init_f´) I linje 5: De to første `semicolonToken´ skal være `commaToken´. I linje 7: Alle rightBracketToken er fjernet. Oppgave 5 --------- `-1´ tas som et numberToken, så Scanneren leverer 5: v = getint()-1; Scanner: nameToken v Scanner: assignToken Scanner: nameToken getint Scanner: leftParToken Scanner: rightParToken Scanner: numberToken -1 Scanner: semicolonToken Løsning: Legg en blank mellom `-´ og `1´. Oppgave 6 --------- LOAD R3,R0,i LOAD R11,R0,x CALL f ADD R4,R3,R3 ADD R1,R4,R1 STORE R1,R3,a