Lösningar till tentamen i EIT070 Datorteknik Institutionen för Elektro- och informationsteknik, LTH Onsdagen den 7 mars 2012, klockan 14:00 19:00 i Vic 2, 3. Tillåtna hjälpmedel: på tentan utdelad formelsamling, miniräknare. Skriv lösningar till varje uppgift på separata ark och använd endast ena sidan på varje ark. Ange namn, program och startår på varje ark. Motivera dina svar tydligt, kommentera all kod du skriver, samt redogör för alla antaganden du gör. Skriv tydligt och läsbart. Betygsgränserna är normalt 20 p för betyg 3, 30 p för betyg 4, och 40 p för betyg 5, av totalt 50 möjliga poäng. Uppgift 1 Betrakta följande blockschema för ett datorsystem som används för mätning och styrning i realtid: Besvara följande frågor: Vilken typ av in- eller utgång skall kretsen D/A vara kopplad till, (2 p)? Vilken typ av in- eller utgång gång skall timern vara kopplad till, (2 p)? Varför är en timer kopplad till datorsystemet, (2 p)? Polling kan ha en fördel jämfört med avbrott. Vilken (2 p)? Vad innebär egentligen begreppet trådar, (2 p)? Kretsen D/A skall vara kopplad till en utport. Timern skall vara kopplad till en avbrottsingång, (på vilken tidsavbrott tas om hand). Timern används för att ge datorsystemet tillgång till en fix, yttre tidmätning, som är oberoende av datorns egen exekveringshastighet. Polling kan gå snabbare än avbrott. Vid avbrottshantering måste man göra ett kontextbyte, vilket normalt sett kräver att man sparar de flesta eller alla register, vilket blir cirka 80-100 instruktioner. Polling behöver inga kontextbyten. Trådar är ett sätt att exekvera oberoende processer så att det ser ut som att flera program exekverar samtidigt, trots att de använder en och samma processor. Sidan 1 av 5.
Uppgift 2 Förklara begreppet semafor inom realtidsprogrammering. Vad används en semafor till, (1 p)? Visa med C- kod och förklaring hur en semafor kan implementeras, (3 p). För att slå på respektive stänga av avbrott kan du använda de två C-subrutinerna enable_interrupts() och disable_interrupts(). En semafor används i ett system med flera trådar eller processer. Des funktion är att skydda gemensamma resurser från att användas samtidigt av flera trådar, så kallad ömsesidig uteslutning. Varje resurs tillordnas en variabel, som visar om resursen är upptagen. Variabeln initialiseras till 1. När en tråd vill använda en resurs, måste den först boka resursen genom ett anrop till wait(sem), och när den har använt resursen måste den släppa den genom ett anrop till signal(sem). void wait(int sem) int busy=1; while (busy) disable_interrupts(); if (sem>0) sem = 0; busy = 0; enable_interrupts(); void signal(int sem) disable_interrupts(); sem=1; enable_interrupts(); Vilka tre register används för att hantera avbrotten i en MIPS-processor? Förklara vad registren heter, vilken funktion de har, samt vilka data de innehåller, (6 p). Status används för att styra vilka avbrott som är aktiva. Här finns enskilda bitar som styr vilka av sex externa och två interna avbrott som ska vara aktiva, samt en generell bit som styr alla användardefinierade avbrott. Cause används av avbrottsprocessorn för at meddela vilka avbrott som kommit. Här finns bitar för de sex externa och två interna avbrotten, och en etta betyder att avbrottet kommit. EPC används för att spara adressen till den instruktion där det körande programmet blev avbrutet av att ett avbrott kom. Efter att avbrottet är hanterat, ska man hoppa tillbaks och fortsätta exekveringen på denna adress. Sidan 2 av 5.
Uppgift 3 Betrakta följande C-funktion: unsigned int strlen(char *s) int i=0; while (s[i]!= 0) i=i+1; callstat( strlen ); return i; Funktionen räknar antalet tecken i en teckensträng. Ett tecken är åtta bitar. En sträng avslutas genom att sista tecknet är noll. Inuti funktionen anropas en statistikrutin som räknar antalet anrop till funktionen strlen. Argumentet är en teckensträng som betyder att anropet gjordes av strlen. Statistikrutinen lämnar ett returvärde i v0, men det används inte av strlen. Skriv din egen version av strlen i MIPS-assembler. Du ska skriva komplett assemblerkod, inklusive direktiv och kommentarer, och du måste följa samtliga MIPS programmeringskonventioner. Förklara vilka skillnader det blir om subrutinen inte anropar callstat, (10 p)..data txt:.ascii strlen # argument for callstat.text.globl strlen.ent strlen strlen: subu sp, sp, 16 # reserve stack space sw ra, 0(sp) # Save value of ra on stack sw a0, 4(sp) # Save value of a0 on stack add t0, zero, zero # initialize t0 to zero repeat: add t1, a0, t0 # compute address to next character lb t2, 0(t1) # load next character (byte) in string beq t2, zero, ready # check if null character, if so ready addi t0, t0, 1 # increment one byte b repeat # repeat for next character ready: sw t0, 8(sp) # store character count on stack la a0, txt # set argument to point to strlen jal callstat # call subroutine callstat lw v0, 8(sp) # fetch computed result from stack lw a0, 4(sp) # restore old value of a0 lw ra, 0(sp) # restore old value of ra addu sp, sp, 16 # pop stack frame jr ra # result is returned in v0.end strlen Om subrutinen inte anropar callstat, behöver strlen inte spara några register eller använda stacken. Sidan 3 av 5.
Uppgift 4 Studera följande satser i språket C: int matrix[50][100], a, b, c; matrix[a][b] = c; Skriv motsvarande kod i MIPS-assembler. Data till matrisen matrix ligger på en adress som heter matrix. Variablerna a, b, och c ligger på adresser som heter just a, b och c. I språket C lagras matriser radvis. Du behöver bara skriva koden för själva tilldelningssatsen, (5 p). la t2, a # load address to a in t2 lw t0, 0(t2) # load value of a in t0 la t2, b # load address to b in t2 lw t1, 0(t2) # load value of b in t1 ori t2, zero, 100 # move value 100 into t2 mult t0, t2 # multiply value of a with 100 (second index) or t0, zero, LO # fetch result of the multiplication add t0, t0, t1 # add values 100 * a + b sll t0, t0, 2 # multiply by four to get address in bytes la t1, matrix # load address of matrix in t1 add t0, t0, t1 # add base address where matrix begins la t2, c # load address to c in t2 lw t1, 0(t2) # load value of c in t1 sw t1, 0(t0) # store value of c at correct place in matrix Förklara hur MIPS maskinspråk stödjer subrutinanrop. Vilka instruktioner finns tillgängliga? Hur är de tänkta att användas? Vilka register används och till vad? (5 p). I MIPS finns särskilda instruktioner som är designade för att hantera subrutinanrop: jal (jump and link) och jalr (jump and link register) hoppar till en viss adress och sparar adressen till efterföljande instruktion i register ra ($31). Man kan hoppa tillbaks från en subrutin med jr ra (jr = jump register) Register $31 eller ra är avsett att alltid innehålla senaste återhoppsadress. Register a1, a2, a3 och a4 är avsedda att innehålla argument (inparametrar) Register v0 och v1 är avsedda att innehålla returvärde Registren s0-s7, sp, fp och gp skall vara oförändrade efter ett anrop, men det gäller inte t0-t9, a0- a4, v0-v1 och ra. Sidan 4 av 5.
Uppgift 5 Studera följande subrutin. Förklara kortfattat men tydligt vad subrutinen gör, (5 p)..globl reset.ent reset reset: ori t0, a0, 0 ori t1, zero, 128 loop: sb zero, 0(t0) addi t0, t0, 1 subi t1, t1, 1 bne t1, zero, loop jr ra.end reset Subrutinen nollställer 128 bytes i minnet, med början på den adress som anges som argument. Följande kod exekveras. la t5, loop lw t6, 12(t5) subi t6, t6, 2 sw t6, 12(t5) Hur förändras subrutinen reset, (5 p)? Adressen till instruktionen loop: sb zero, 0(t0) laddas i register t5. Tre words (12 bytes) längre fram ligger instruktionen bne t1, zero, loop, och det är alltså bitmönstret till denna instruktion som laddas i register t6. Bitmönstret minskas med 2 och skrivs sedan tillbaks. Det är bara det sista delfältet i branchinstruktionen som påverkas av subtraktionen. Det innebär att branchinstruktionen kommer att hoppa två instruktioner längre bakåt. Annorlunda uttryckt: Instruktionen förändras till bne t1, zero, loop bne t1, zero, reset Lycka till! Sidan 5 av 5.