Professional Documents
Culture Documents
Car Week 5 440905
Car Week 5 440905
Car Week 5 440905
WEEK 5
Davy van Weijen| 440905 | 1G
We slaan de waarden uit array1 van achter naar voren op in de stack (push) , waarbij
we de waarden die gelijk zijn aan x overslaan. Vervolgens lezen we de waarden 1
voor 1 van de stack (pop) en vullen daarmee de resultaat array array2. In
“stack_student.s” is de structuur van het programma gegeven.
-
b) Vergelijk de geheugenadressen van de waarden die op de stack worden
gepushed. Wordt een volgende waarde weggeschreven op een hoger of lager
geheugenadres?
c) Wat gebeurt er als je buiten het gealloceerde data segment voor arr1 en arr2
schrijft? Je kunt dit proberen door in het gegeven programma
addi x28, zero, 0xff
sw x28, 100(x7)
sw x28, -100(x7)
toe te voegen.
1
2/10
d) Wat gebeurt als je buiten de stack schrijft? Je kunt dit proberen door in het
gegeven programma
addi x28, zero, 0xf
sw x28, 100(sp)
sw x28, -100(sp)
toe te voegen.
e) Voer het volgende commando uit aan het eind van het programma en verklaar
het resultaat.
addi x28, zero, 0xf
sw x28, 6(sp)
Dan verschijnt er een foutmelding die zegt “Runtime exception: store address not
aligned on word boundary.”
Dit komt doordat sw een word wil wegschrijven van 4 bytes. Dit is alleen
mogelijk met een offset die een veelvou van vier is.
We gebruiken hiervoor twee procedures. Allereerst een procedure square, zie code in
“square.s”, die voor een gegeven geheel getal het kwadraat van dat getal berekent en
retourneert. Daarnaast de procedure euclid die het kwadraat van de elementen in een
array berekent en daarvoor de procedure square meerdere maken aanroept. Een deel
van de code is gegeven in “euclid.s”.
In “euclid.run.s” is code gegeven waarin een tweetal arrays worden gedefinieerd en
waarvan vervolgens de som van de kwadraten wordt berekend door de procedure
euclid aan te roepen.
a) Welke registers kunnen gebruikt worden om een procedure van input waarden te
voorzien?
Registers: a0, a1, a2, a3, a4, a5, a6 en a7
Dit zijn dus ook: x10, x11, X12, x13, x14, x15, x16 en x17
2
3/10
b) Welke registers kunnen gebruikt worden om het resultaat van een procedure in
op te slaan?
Registers: a0 en a1
Dit zijn dus ook: x10 en x11
c) Welke registers mogen door een procedure niet van waarde veranderen, d.w.z.
na afloop van de procedure moet de waarde gelijk zijn aan de beginwaarde?
s0 tot en met s11, dit zijn dus x8, x9 en x18 tot en met x27.
Stack-pointer: sp = x2
Return-adres = x1
d) Als een van deze register genoemd bij c) tijdens de uitvoering van een
procedure wordt gewijzigd, bijvoorbeeld omdat er een andere procedure wordt
aangeroepen, dan moet de procedure deze waarden aan begin van de
procedure opslaan op de stack en aan het eind van de procedure de waarden uit
de stack terugplaatsen in de betreffende registers en de ruimte op de stack
vrijgeven.
Voeg de code toe in “euclid.s” om de benodigde info op de stack op te slaan en
weer uit te lezen, zie regels beginnend met “# add code to ”
3
4/10
4
5/10
De Fibonacci reeks bestaat uit de volgende getallen: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
fib[0]=0 en fib[1] =1
Schrijf een programma dat de eerste 100 fibonacci getallen berekend en opslaat in het
data segment, zodat we de berekende waardes in een ander deel van het programma
kunnen gebruiken. Maak gebruik van een loop waarbij in elke loop het volgende
fibonacci getal wordt berekend. Uitkomsten kun je controleren met
http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html#100.
a) Eerst controleren we hoeveel ruimte er in het data segment is. Via Settings = >
Memory Configuration kun je de default configuratie van het geheugen bekijken.
Het data segment begint bij het “data segment base address” en loopt tot het
“heap base address”.
Hoeveel getallen van 64 bits kunnen we dus opslaan in het data segment?
3 x 213 = 24576
Pas het programma uit “fibonacci_student.s” aan zodat het de fibonacci getallen opslaat
in het data segment.
5
6/10
6
7/10
7
8/10
Run het programma zodat de fibonacci getallen worden berekend en weggeschreven in het
data segment.
a) Waarom hoeft er aan het eind van het init blok geen jump naar het fibloop blok te
worden opgenomen?
- Het blok: fiboop bevat de eerstvolgende instructie en wordt dus uitgevoerd na
de afloop van init
b) Zoek de waarde 0x2ff42 van fib[27] op in het data segment. Wat is het
geheugenadres van deze waarde en welke adressen worden gebruikt om deze
waarde op te slaan?
- 0x100100d8, klopt.
c) Zoek de waarde 196418 van fib[27] op in het data segment. Wat is het
geheugenadres van deze waarde?
0x2ff42 = 196418, dit staat op geheugenadres 268501208 = 0x100100d8
d) Een oplettende student ziet in de simulator in het data segment op adres
268501368, oftewel 268501344(+24), voor het eerst een negatief getal staan, zie
ook onderstaand screenshot (let op: geheugenadressen en waardes zijn decimaal
weergegeven).
8
9/10
Met behulp van het programma “add_abs_test.s” kan de werking van de beide procedures
worden getest.
9
10/10
10