Πανεπιστήμιο Θεσσαλίας Τμήμα Μηχανικών Η/Υ, Τηλεπικοινωνιών και Δικτύων

Σχετικά έγγραφα
Πανεπιστήμιο Θεσσαλίας Τμήμα Πληροφορικής

Πανεπιστήμιο Θεσσαλίας Τμήμα Πληροφορικής. Εισαγωγή στους Η/Υ

Οργάνωση Η/Υ. Γιώργος ηµητρίου. Μάθηµα 2 ο. Πανεπιστήµιο Θεσσαλίας - Τµήµα Μηχανικών Η/Υ, Τηλεπικοινωνιών και ικτύων

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 2 ο. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

Πανεπιστήμιο Θεσσαλίας Τμήμα Μηχανικών Η/Υ, Τηλεπικοινωνιών και Δικτύων

Πανεπιστήμιο Θεσσαλίας Τμήμα Πληροφορικής. Εισαγωγή στους Η/Υ

Οργάνωση Υπολογιστών

Αρχιτεκτονική Υπολογιστών Ι

1 η Ενδιάμεση Εξέταση Απαντήσεις/Λύσεις

Οργάνωση Η/Υ. Γιώργος Δημητρίου. Μάθημα 2 ο Σύντομη Επανάληψη. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

Ελίνα Μακρή

ΤΕΧΝΟΛΟΓΙΚΟ ΕΚΠΑΙΔΕΥΤΙΚΟ ΙΔΡΥΜΑ ΛΑΜΙΑΣ. A. Μετατροπή αριθμών 1. Μετατροπή αριθμών από δεκαδικό σε δυαδικό σύστημα αρίθμησης

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ Η/Υ ΠΡΩΤΗ ΠΡΟΟΔΟΣ ΣΤΗΝ «ΟΡΓΑΝΩΣΗ ΚΑΙ ΣΧΕΔΙΑΣΗ Η/Y»

Πανεπιστήμιο Θεσσαλίας Τμήμα Μηχανικών Η/Υ, Τηλεπικοινωνιών και Δικτύων

ΕΘΝΙKΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΕΡΓΑΣΤΗΡΙΟ ΥΠΟΛΟΓΙΣΤΙΚΩΝ ΣΥΣΤΗΜΑΤΩΝ. Ονοματεπώνυμο: ΑΜ:

Εισαγωγή στην επιστήμη των υπολογιστών

Κεφάλαιο 2. Συστήματα Αρίθμησης και Αναπαράσταση Πληροφορίας. Περιεχόμενα. 2.1 Αριθμητικά Συστήματα. Εισαγωγή

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Τμήμα Πληροφορικής

Εντολές γλώσσας μηχανής

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Πανεπιστήµιο Θεσσαλίας Τµήµα Μηχανικών Η/Υ, Τηλεπικοινωνιών και ικτύων

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Τμήμα Πληροφορικής

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

Οργάνωση Υπολογιστών

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 3-4: Προγραμματισμός MIPS. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

2ο ΓΕΛ ΑΓ.ΔΗΜΗΤΡΙΟΥ ΑΕΠΠ ΘΕΟΔΟΣΙΟΥ ΔΙΟΝ ΠΡΟΣΟΧΗ ΣΤΑ ΠΑΡΑΚΑΤΩ

ΠΛΗΡΟΦΟΡΙΚΗ I Ενότητα 6

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 7 και 8: Αναπαραστάσεις. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

d k 10 k + d k 1 10 k d d = k i=0 d i 10 i.

Συστήματα αρίθμησης. = α n-1 *b n-1 + a n-2 *b n-2 + +a 1 b 1 + a 0 όπου τα 0 a i b-1

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

1. Πότε χρησιμοποιούμε την δομή επανάληψης; Ποιες είναι οι διάφορες εντολές (μορφές) της;

Αριθμητικά Συστήματα

add $t0,$zero, $zero I_LOOP: beq $t0,$s3, END add $t1, $zero,$zero J_LOOP: sub $t2, $s3, $t0 add $t2, $t2, $s1 int i, j, tmp; int *arr, n;

Διαδικασίες Ι. ΗΥ 134 Εισαγωγή στην Οργάνωση και στον Σχεδιασμό Υπολογιστών Ι. Διάλεξη 4

Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής. Οργάνωση Η/Υ. Γιώργος ηµητρίου. Μάθηµα 2 ο Σύντοµη Επανάληψη

2. ΑΡΙΘΜΗΤΙΚΗ ΤΟΥ ΥΠΟΛΟΓΙΣΤΗ. 2.1 Αριθμητικά συστήματα

1 Αριθμητική κινητής υποδιαστολής και σφάλματα στρογγύλευσης

Συναρτήσεις-Διαδικασίες

ΑΡΧΙΤΕΚΤΟΝΙΚΗ ΥΠΟΛΟΓΙΣΤΩΝ. Κεφάλαιο 3

Οργάνωση Η/Υ. Ο Επεξεργαστής TRN. Τμήμα Εφαρμοσμένης Πληροφορικής Πανεπιστήμιο Μακεδονίας Α. Χατζηγεωργίου-Η. Σακελλαρίου

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΣΧΟΛΙΚΟΥ ΕΤΟΥΣ

Αριθμητική Ανάλυση & Εφαρμογές

Μεταγλωττιστές. Γιώργος Δημητρίου. Μάθημα 11 ο. Πανεπιστήμιο Θεσσαλίας - Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΠΡΟΣΟΜΟΙΩΣΗΣ ΠΑΝΕΛΛΑΔΙΚΩΝ ΣΧΟΛΙΚΟΥ ΕΤΟΥΣ

2 ΟΥ και 8 ΟΥ ΚΕΦΑΛΑΙΟΥ

Εργαστήριο ΨΗΦΙΑΚΗ ΛΟΓΙΚΗ. Εισαγωγή

ΚΕΦΑΛΑΙΟ 8 Η ΓΛΩΣΣΑ PASCAL

ΕΠΛ605 Εργασία 1 Ημερομηνία Παράδοσης 12/9/2018 στην αρχή του μαθήματος

Σύστημα Πλεονάσματος και Αναπαράσταση Αριθμών Κινητής Υποδιαστολής

Δυαδικό Σύστημα Αρίθμησης

Πρόγραμμα Επικαιροποίησης Γνώσεων Αποφοίτων ΑΡΙΘΜΗΤΙΚΑ ΣΥΣΤΗΜΑΤΑ

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών

Σύστημα Πλεονάσματος. Αναπαράσταση Πραγματικών Αριθμών. Αριθμητικές Πράξεις σε Αριθμούς Κινητής Υποδιαστολής

Εισαγωγή στην Πληροφορική & τον Προγραμματισμό

ΟΡΓΑΝΩΣΗ ΚΑΙ ΣΧΕΔΙΑΣΗ Η/Υ

ΠΛΗ21 Κεφάλαιο 2. ΠΛΗ21 Ψηφιακά Συστήματα: Τόμος Α Κεφάλαιο: Παράσταση Προσημασμένων Αριθμών Συμπληρώματα

Εντολές του MIPS (2)

1. ΣΥΣΤΗΜΑΤΑ ΑΡΙΘΜΩΝ. α i. (α i β i ) (1.3) όπου: η= το πλήθος ακεραίων ψηφίων του αριθμού Ν. n-1

Αρχιτεκτονική Υπολογιστών Ι

Αρχιτεκτονική Υπολογιστών

ΗΥ 232 Οργάνωση και Σχεδίαση Υπολογιστών. Διάλεξη 3 Εντολές του MIPS (2)

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ

Τμήμα Χρηματοοικονομικής & Ελεγκτικής ΤΕΙ Ηπείρου Παράρτημα Πρέβεζας. Πληροφορική Ι. Αναπαράσταση αριθμών στο δυαδικό σύστημα. Δρ.

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. Τρίτη (3 η ) δίωρη διάλεξη. Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

ΑΕΠΠ Ερωτήσεις θεωρίας

ΕΡΓΑΣΤΗΡΙΟ ΑΡΧΙΤΕΚΤΟΝΙΚΗΣ Η/Υ

Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής. Οργάνωση Η/Υ. Γιώργος Δημητρίου. Μάθημα 3 ο ΜΕΔ απλού κύκλου

ΠΡΟΓΡΑΜΜΑ ΣΠΟΥ ΩΝ ΠΛΗΡΟΦΟΡΙΚΗΣ

Διαδικασιακός Προγραμματισμός

Διαδικασίες ΙI. ΗΥ 134 Εισαγωγή στην Οργάνωση και στον Σχεδιασμό Υπολογιστών Ι. Διάλεξη 5

1 η Άσκηση Στην Αρχιτεκτονική Υπολογιστών

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

ΜΥΥ- 402 Αρχιτεκτονική Υπολογιστών Φροντιστήριο: MIPS assembly

Λογική Σχεδίαση Ψηφιακών Συστημάτων

2η ΑΣΚΗΣΗ ΣΤΗΝ ΑΡΧΙΤΕΚΤΟΝΙΚΗ ΥΠΟΛΟΓΙΣΤΩΝ Ακ. έτος , 5ο Εξάμηνο Σχολή ΗΜ&ΜΥ

1 η Θεµατική Ενότητα : Δυαδικά Συστήµατα

Αριθμητικά Συστήματα

Λύσεις 1 ης Ενδιάμεσης Εξέτασης στο ΗΜΥ213

! Εάν ο αριθμός διαθέτει περισσότερα bits, χρησιμοποιούμε μεγαλύτερες δυνάμεις του 2. ! Προσοχή στη θέση του περισσότερο σημαντικού bit!

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών Τμήμα Πληροφορικής

ΠΛΗΡΟΦΟΡΙΚΗ I. 4 η ΔΙΑΛΕΞΗ Αριθμητικά Συστήματα

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 11 ο και 12 ο

Έστω ένας πίνακας με όνομα Α δέκα θέσεων : 1 η 2 η 3 η 4 η 5 η 6 η 7 η 8 η 9 η 10 η

53 Χρόνια ΦΡΟΝΤΙΣΤΗΡΙΑ ΜΕΣΗΣ ΕΚΠΑΙΔΕΥΣΗΣ Σ Α Β Β Α Ϊ Δ Η Μ Α Ν Ω Λ Α Ρ Α Κ Η

Πανεπιστήμιο Θεσσαλίας Τμήμα Πληροφορικής

Αρχιτεκτονική υπολογιστών

Πράξεις με δυαδικούς αριθμούς

Αριθμητική Υπολογιστών (Κεφάλαιο 3)

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

3.1 Αριθμητικοί και Λογικοί Τελεστές, Μετατροπές Τύπου (Casting)

Προγραμματισμός Ι (HY120)

Ψηφιακά Συστήματα. 1. Συστήματα Αριθμών

Transcript:

Πανεπιστήμιο Θεσσαλίας Τμήμα Μηχανικών Η/Υ, Τηλεπικοινωνιών και Δικτύων Οργάνωση Η/Υ Ενότητα 2η: Αναπαράσταση Πληροφορίας - Σύνολα Εντολών Άσκηση 1: Να αποδείξετε ότι η μοναδική μη προσημασμένη ακέραια αναπαράσταση του αριθμού με τιμή 0 σε αριθμητικό σύστημα οποιασδήποτε βάσης είναι η 0 0, για οποιοδήποτε μέγεθος αναπαράστασης. Επεκτείνατε για προσημασμένη αναπαράσταση συμπληρώματος ως προς βάση. Απάντηση: Έστω αριθμητικό σύστημα με βάση q, στο οποίο ένας αριθμός αναπαριστάνεται με n το πλήθος ψηφία, όπου q και n τυχαίοι θετικοί ακέραιοι. Στο σύστημα αυτό υπάρχουν q διαφορετικά ψηφία με διαφορετικές ακέραιες τιμές από 0 έως q-1. Λόγω της 1-1 αντιστοίχησης μεταξύ ψηφίων και τιμών τους, χρησιμοποιούμε τον ίδιο συμβολισμό τόσο για τα ψηφία της αναπαράστασης, όσο και για τις τιμές τους. Έστω λοιπόν ένας μη προσημασμένος αριθμός Ν Α n-1 A n-2 A 1 A 0 στο πιο πάνω σύστημα, με τιμή που δίνεται από τη σχέση: T(N) = A n-1 q n-1 +A n-2 q n-2 + +A 1 q+a 0 με q > Α i 0, i = 0,,n-1 Αν ο αριθμός Ν έχει τιμή 0, έχουμε: T(N) = 0 A n-1 q n-1 +A n-2 q n-2 + +A 1 q+a 0 = 0 (1) Αφού όμως η βάση q είναι θετικός αριθμός, η παραπάνω σχέση με άγνωστους τις μη αρνητικές τιμές των ψηφίων του αριθμού Ν έχει μοναδική λύση την A i = 0, i = 0,,n-1 γιατί αν έστω και κάποιο ψηφίο του Ν ήταν μη μηδενικό, έστω το A k, 0 k n-1, θα είχαμε: T(N) A k q k > 0 Επομένως η μοναδική μη προσημασμένη ακέραια αναπαράσταση του 0 είναι η 0 0 για οποιαδήποτε q και n. Αν τώρα η αναπαράσταση είναι προσημασμένη σε μορφή συμπληρώματος ως προς βάση, τα παραπάνω αποδεικνύουν ότι η αναπαράσταση 0 0 είναι η μοναδική αναπαράσταση του 0 στους αριθμούς με μη αρνητική τιμή. Αρκεί επομένως να δείξουμε ότι οι αντίθετοι αυτών, δηλαδή οι αριθμοί με μη θετική τιμή, περιλαμβάνουν την ίδια ακριβώς αναπαράσταση του 0, και μόνο αυτή. Στην προσημασμένη αναπαράσταση συμπληρώματος ως προς βάση, η εύρεση του αντιθέτου ενός αριθμού γίνεται με μετατροπή των ψηφίων του αριθμού στα συμπληρωματικά τους και επακόλουθη αύξηση του νέου αριθμού κατά 1. Έτσι, ο αντίθετος του παραπάνω αριθμού Ν θα είναι ο Ν +1, όπου Ν Α n-1 A n-2 A 1 A 0, και A i = q-1-a i, i = 0,,n-1. Αν τυχόν κατά την αύξηση προκύψει κρατούμενο εξόδου, αυτό απορρίπτεται. Η τιμή ενός μη θετικού αριθμού Ν n ψηφίων θα δίνεται επομένως από τη σχέση: T(N) = -[(Τ(Ν ) + 1) mod q n ] = = -[(A n-1 q n-1 +A n-2 q n-2 + +A 1 q+a 0 +1) mod q n ] = = -{[(q-1-a n-1 ) q n-1 +(q-1-a n-2 ) q n-2 + +(q-1-a 1 ) q+(q-1-a 0 )+1] mod q n } =

2 = -{[(q-1) (q n-1 +q n-2 + +q+1)-(a n-1 q n-1 +A n-2 q n-2 + +A 1 q+a 0 )+1] mod q n }= = -{[(q n -1) - (A n-1 q n-1 +A n-2 q n-2 + +A 1 q+a 0 ) + 1] mod q n } = = -{[q n - (A n-1 q n-1 +A n-2 q n-2 + +A 1 q+a 0 )] mod q n } όπου η συνάρτηση mod εκφράζει την απόρριψη κρατούμενου εξόδου στην έκφραση Ν +1. Εφόσον τα ψηφία A i έχουν τιμές από 0 έως q-1, η έκφραση μέσα στις παρενθέσεις έχει τιμές από 0 έως q n -1. Έτσι, για μη μηδενική τιμή της έκφρασης στις παρενθέσεις, η συνολική έκφραση δε μπορεί να έχει μηδενική τιμή. Αν όμως η έκφραση στις παρενθέσεις έχει μηδενική τιμή, η διαφορά q n -0 θα μηδενιστεί μετά την εφαρμογή της συνάρτησης mod. Άρα για μηδενική τιμή του μη θετικού αριθμού Ν καταλήγουμε πάλι στην έκφραση (1), κι επομένως ο αριθμός 0 0 είναι η μοναδική αναπαράσταση του 0 για όλους τους προσημασμένους αριθμούς της αναπαράστασης συμπληρώματος ως προς βάση. Άσκηση 2: Α. Να μετατραπούν οι αριθμοί 63205 10, 1038 10 και 15261 10 στους αντίστοιχους δεκαεξαδικούς, οκταδικούς και δυαδικούς αριθμούς. Β. Να παρασταθεί σε μορφή κινητής υποδιαστολής ΙΕΕΕ 754 των 32 bits ο αριθμός -5,0 10. Γ. Τι παριστάνεται με καθεμιά από τις ομάδες των 7 bits: 040, 077, 111, 134 (εκφρασμένων σε συμπτυγμένη μορφή στο οκταδικό σύστημα), όταν ερμηνευτεί: α) ως ακέραιος σε παράσταση συμπληρώματος του 1 β) ως ακέραιος σε παράσταση συμπληρώματος του 2 γ) ως ακέραιος σε παράσταση πρόσημο-μέτρο δ) ως μη προσημασμένος ακέραιος ε) ως ASCII χαρακτήρας Απάντηση: Α. Μπορούμε να ξεκινήσουμε τη λύση με τη μετατροπή των αριθμών σε οποιοδήποτε από τα τρία ζητούμενα συστήματα. Εφ όσον δεν έχουμε περιορισμό στον αριθμό των ψηφίων που θα πάρουμε, ο αριθμός των βημάτων του αλγόριθμου μετατροπής καθορίζεται από τον αριθμό των διαιρέσεων που θα εκτελέσουμε, το οποίο σημαίνει ότι η μετατροπή στο σύστημα με τη μεγαλύτερη βάση (δηλαδή στο δεκαεξαδικό) είναι η πιο γρήγορη. Επειδή ακόμα η μετατροπή μεταξύ των τριών συστημάτων δεν απαιτεί νέες διαιρέσεις, εφ όσον η βάση 8 και η βάση 16 είναι δυνάμεις της τρίτης βάσης 2, αρκεί να εφαρμόσουμε τον αλγόριθμο μετατροπής μόνο για τη βάση 16. Έχουμε λοιπόν: x[0] = 63205 63205 = 16 3950 + 5, δηλαδή a 0 = 5 και x[1] = 3950 3950 = 16 246 + 14, δηλαδή a 1 = 14 και x[2] = 246 246 = 16 15 + 6, δηλαδή a 2 = 6 και x[3] = 15 15 = 16 0 + 15, δηλαδή a 3 = 15 και x[4] = 0 Επομένως: 63205 10 = f6e5 16 Επειδή 16 = 2 4, η μετατροπή του δεκαεξαδικού αριθμού σε δυαδικό γίνεται με ανάπτυξη κάθε δεκαεξαδικού ψηφίου σε δυαδικό: f6e5 16 = 1111011011100101 2 Τέλος, για να πάμε στο οκταδικό σύστημα, παρατηρούμε ότι 8 = 2 3, κι επομένως η μετατροπή του δυαδικού αριθμού σε οκταδικό γίνεται με σύμπτυξη των δυαδικών ψηφίων ανά 3. Για τη μετατροπή αυτή προεκτείνουμε (δηλαδή συμπληρώνουμε προς τα αριστερά) το δυαδικό α-

3 ριθμό, έτσι ώστε ο αριθμός των δυαδικών ψηφίων να γίνει πολλαπλάσιο του 3. Επειδή ο αρχικός αριθμός είναι θετικός, θα συμπληρώσουμε με δύο ψηφία 0. Άρα ο αριθμός γίνεται: 001111011011100101 2 = 173345 8 Σημειώστε ότι η μετατροπή στο οκταδικό σύστημα δε μπορεί να γίνει απ ευθείας από το δεκαεξαδικό, επειδή το 16 δεν είναι δύναμη του 8. Συνεχίζοντας για τους υπόλοιπους αριθμούς: x[0] = 1038 1038 = 16 64 + 14, δηλαδή a 0 = 14 και x[1] = 64 64 = 16 4 + 0, δηλαδή a 1 = 0 και x[2] = 4 4 = 16 0 + 4, δηλαδή a 2 = 4 και x[3] = 0 Επομένως: 1038 10 = 40e 16 και συνεχίζοντας όπως παραπάνω: 40e 16 = 10000001110 2 = 4036 8 Τέλος: x[0] = 15261 15261 = 16 953 +13, δηλαδή a 0 = 13 και x[1] = 953 953 = 16 59 + 9, δηλαδή a 1 = 9 και x[2] = 59 59 = 16 3 + 11, δηλαδή a 2 = 11 και x[3] = 3 3 = 16 0 + 3, δηλαδή a 3 = 3 και x[4] = 0 και άρα 1 : 15261 10 = 3b9d 16 = 011101110011101 2 = 35635 8 Β. Στην ζητούμενη παράσταση ο συντελεστής απεικονίζεται με την τεχνική πρόσημο-μέτρο. Επομένως, θα υπολογίσουμε την παράσταση για το μέτρο του αριθμού, και στο τέλος θα θέσουμε την τιμή 1 στο πιο σημαντικό bit αυτής. Έτσι: 5,0 10 = 101,0 2 και σε μορφή κινητής υποδιαστολής: 5,0 10 = 101,0 2 2 0 Για να κανονικοποιήσουμε την πιο πάνω παράσταση, την μετατρέπουμε σε ισοδύναμη (δηλαδή ίσης τιμής) με μεταφορά της υποδιαστολής προς τα αριστερά και ταυτόχρονη αύξηση της τιμής του εκθέτη: 5,0 10 = 1,01 2 2 2 Για να μεταβούμε στη μορφή ΙΕΕΕ 754, εκφράζουμε τον εκθέτη σε πολωμένη παράσταση, προσθέτοντας το 127: 5,0 10 = 1,01 2 2 (129-127) Άρα για την τελική μορφή του αριθμού θα έχουμε: σ = 01000 0 ε = 10000001 π = 1 δηλαδή ο αριθμός θα παρασταθεί ως: 11000000101000000000000000000000 Γ. Για τις ερωτήσεις (α) έως (δ) θέλουμε να βρούμε την αναπαριστώμενη τιμή στο δεκαδικό σύστημα. Κατ αρχήν αναπτύσσουμε τους αριθμούς στην πλήρη δυαδική τους μορφή. Έτσι, διαπιστώνουμε ότι οι πρώτοι δύο αριθμοί είναι θετικοί, κι επομένως η τιμή τους είναι η ίδια 1 Σε επόμενες ασκήσεις οι δεκαεξαδικοί αριθμοί θα αναγράφονται με το πρόθεμα 0x αντί του δείκτη 16, όπως συνηθίζεται σε πολλές γλώσσες προγραμματισμού, τόσο υψηλού όσο και χαμηλού επιπέδου.

4 για όλες τις ερωτήσεις (α) έως (δ). Για τους υπόλοιπους δύο βρίσκουμε πρώτα τον αντίστοιχο θετικό δυαδικό. Για την ερώτηση (δ) θεωρούμε το πιο σημαντικό δυαδικό ψηφίο σα μέρος του μέτρου του αριθμού. Τέλος για τους ASCII χαρακτήρες ανατρέχουμε στον αντίστοιχο πίνακα. Σχηματίζουμε έτσι τον πιο κάτω πίνακα που συμπληρώνουμε με τις απαντήσεις: οκταδικός 040 077 111 134 δυαδικός 0100000 0111111 1001001 1011100 (α) -0110110 = -54 10-0100011 = -35 10 (β) -0110111 = -55 32 10 63 10-0100100 = -36 10 (γ) 10-001001 = -9 10-011100 = -28 10 (δ) 73 10 92 10 (ε)? I \ Άσκηση 3: Θεωρήστε το αριθμητικό σύστημα σταθερής υποδιαστολής με βάση 3, μεγέθους 6 ψηφίων, στο οποίο τα 4 πρώτα ψηφία είναι ακέραια και τα υπόλοιπα 2 ψηφία είναι κλασματικά, για προσημασμένους αριθμούς σε συμπλήρωμα ως προς βάση. Βρείτε την αναπαράσταση στο σύστημα αυτό των αριθμών: +24,3-38,25-7,872 +10-42,6 +0,333 οι οποίοι δίνονται στο δεκαδικό σύστημα σε πρόσημο/μέτρο. Στη συνέχεια υπολογίστε την τιμή των αριθμών της νέας αναπαράστασης και βρείτε πόσο κοντά είναι στην τιμή των αρχικών αριθμών. Απάντηση: Στο αριθμητικό σύστημα που μας δίνεται, οι αριθμοί που περιλαμβάνονται είναι όλες οι διατάξεις των 6 ψηφίων με 3 δυνατές τιμές κάθε ψηφίου, δηλαδή ένα πλήθος 3 6 = 729 αριθμών. Για προσημασμένη αναπαράσταση σε συμπλήρωμα ως προς βάση, έχουμε μόνο μία απεικόνιση του 0, κι επομένως θα έχουμε 729-1 = 728 μη μηδενικούς αριθμούς, που για ίσο πλήθος θετικών και αρνητικών, θα είναι 364 θετικοί και 364 αρνητικοί αριθμοί. Από τη μία ανεβαίνοντας, και από την άλλη κατεβαίνοντας από το 0, βρίσκουμε το σημείο στο οποίο ο μέγιστος θετικός συναντιέται με τον ελάχιστο αρνητικό. Έτσι, ο μέγιστος θετικός θα είναι ο 111111, με τιμή 1 3 3 + 1 3 2 + 1 3 + 1 + 1 3-1 + 1 3-2 = 40,4444... (= 364 3-2 ) και αντίστοιχα ο ελάχιστος αρνητικός θα είναι ο 111112, με τιμή -40,4444... Με βάση τα παραπάνω, καταλαβαίνουμε ότι το σύστημά μας δεν μπορεί να απεικονίσει τον αριθμό -42,6, αφού είναι μικρότερος από τον ελάχιστο αρνητικό της αναπαράστασης. Για όλους τους υπόλοιπους, εφαρμόζουμε τον αλγόριθμο μετατροπής για το μέτρο του αριθμού, ξεχωριστά για το ακέραιο και ξεχωριστά για το κλασματικό μέρος, και αν ο αριθμός είναι αρνητικός, βρίσκουμε στη συνέχεια το συμπλήρωμα ως προς βάση της αναπαράστασης του μέτρου. Για παράδειγμα, για τον πρώτο αριθμό, η μετατροπή του ακέραιου μέρους 24 γίνεται με διαδοχικές διαιρέσεις με το 3: 24 3 = 8 με υπόλοιπο 0 (άρα λιγότερο σημαντικό ψηφίο = 0)

5 8 3 = 2 με υπόλοιπο 2 (άρα επόμενο ψηφίο = 2) 2 3 = 0 με υπόλοιπο 2 (άρα επόμενο ψηφίο = 2) και συμπληρώνουμε με 0, εφόσον μετατρέπουμε το μέτρο του αριθμού. Η μετατροπή του κλασματικού μέρους 3 γίνεται με διαδοχικούς πολλαπλασιασμούς με το 3: 0,3 3 = 0,9 (άρα πρώτο κλασματικό ψηφίο = 0) 0,9 3 = 2,7 (άρα δεύτερο κλασματικό ψηφίο = 2) και σταματάμε, εφόσον υπολογίζουμε δύο κλασματικά ψηφία. Όλοι οι υπολογισμοί φαίνονται στον παρακάτω πίνακα: Αριθμός Μέτρο Ακέραιο μέρος Κλασματικό μέρος Νέο μέτρο Νέος αριθμός +24,3 24,3 24 0220 3 02 022002 022002-38,25 38,25 38 1102 25 02 110202 112021-7,872 7,872 7 0021 872 21 002121 220101 +10 10 10 0101 0 00 010100 010100-42,6 - +0,333 0,333 0 0000 333 02 000002 000002 Η διαδικασία της μετατροπής που ακολουθήσαμε υπολογίζει τα κλασματικά μέρη χωρίς καμία προσπάθεια βέλτιστης προσέγγισης του αρχικού αριθμού. Παρατηρήστε ότι στο παράδειγμα του κλασματικού 3 (δηλαδή του αριθμού 0,3) ο δεύτερος πολλαπλασιασμός έδωσε αποτέλεσμα που είναι πιο κοντά στο 2+1 παρά στο 2, κι επομένως θα μπορούσαμε να προσεγγίσουμε το 0,3 καλύτερα με το 10 (με τιμή 0,3333...) παρά με το 02 (με τιμή 0,2222...). Ας δούμε πόσο κοντά είμαστε για καθέναν από τους αριθμούς που μετατρέψαμε, υπολογίζοντας την τιμή του αποτελέσματος: Τ(022002) = 0 3 3 + 2 3 2 + 2 3 + 0 + 0 3-1 + 2 3-2 = +24,2222... Τ(112021) = -Τ(110202) = -(1 3 3 + 1 3 2 + 0 3 + 2 + 0 3-1 + 2 3-2 ) = -38,2222... Τ(220101) = -Τ(002122) = -(0 3 3 + 0 3 2 + 2 3 + 1 + 2 3-1 + 2 3-2 ) = -7,8888... Τ(010100) = 0 3 3 + 1 3 2 + 0 3 + 1 + 0 3-1 + 0 3-2 = +10 Τ(000002) = 0 3 3 + 0 3 2 + 0 3 + 0 + 0 3-1 + 2 3-2 = +0,2222... Για όλες τις περιπτώσεις η διαφορά της τιμής της αναπαράστασης από την τιμή του αρχικού αριθμού είναι κατ απόλυτη τιμή μικρότερη από την ακρίβεια του συστήματος, η οποία είναι: ακρίβεια συστήματος Τ(000001) = 0,1111... Άσκηση 4: Για ένα αριθμητικό σύστημα με βάση Β, στο οποίο διατίθενται κ ψηφία για την αναπαράσταση των αριθμών, μετράμε την αποτελεσματικότητα αποθήκευσης με το δείκτη κόστους Ε = κ Β που υποθέτει ότι το κόστος αποθήκευσης για κάθε ψηφίο είναι ανάλογο με τον αριθμό τιμών που μπορεί αυτό να πάρει. Αν το πλήθος Α των αριθμών που θέλουμε να αναπαραστήσουμε είναι σταθερό, να βρεθεί η βάση Β που ελαχιστοποιεί το Ε. Απάντηση: Το πλήθος Α των τιμών που αναπαρασταίνουμε δίνεται από τη σχέση: Α = Β κ από την οποία παίρνουμε: κ = lna/lnb Αντικαθιστώντας στη σχέση που μας δίνεται:

6 Ε = κ Β Ε = lna B / lnb Για να ελαχιστοποιήσουμε το Ε ως προς Β, πρέπει να μηδενίσουμε την αντίστοιχη παράγωγο: de/db = 0 lna (lnb 1) / ln 2 B = 0 lnb = 1 B = e δεδομένου ότι Α 1, Β 1. Βρίσκουμε εύκολα χρησιμοποιώντας τη δεύτερη παράγωγο ότι η τιμή e όντως ελαχιστοποιεί το δείκτη Ε. Επειδή ζητάμε ακέραιο Β, εξετάζουμε τις τιμές της συνάρτησης για Β = 2 και Β = 3. Έχουμε: 2/ln2 > 3/ln3 κι επομένως η βάση Β που ζητάμε είναι 3. Άσκηση 5: Έστω ένας επεξεργαστής αρχιτεκτονικής στοίβας. Στον επεξεργαστή αυτόν κάθε αριθμητική πράξη εκτελείται με υπονοούμενα τελούμενα εισόδου τα δύο στοιχεία στην κορυφή της στοίβας. Ειδικότερα, το πρώτο στοιχείο από την κορυφή της στοίβας αποτελεί το αριστερό, ενώ το δεύτερο στοιχείο από την κορυφή της στοίβας αποτελεί το δεξί τελούμενο της πράξης. Τα στοιχεία της στοίβας φορτώνονται από και αποθηκεύονται στη μνήμη με τις ειδικές εντολές push και pop αντίστοιχα, που λαμβάνουν μοναδικό τελούμενο μια διεύθυνση μνήμης για κατ ευθείαν διευθυνσιοδότηση. Α. Γράψτε το συντομότερο δυνατό κώδικα συμβολικής γλώσσας του πιο πάνω επεξεργαστή για τον υπολογισμό της έκφρασης: Z = A*B - C*(D + E/F) όπου A, B, C, D, E, F και Z αριθμητικές μεταβλητές, οι οποίες αντιστοιχούνται σε διευθύνσεις μνήμης που συμβολίζονται με το όνομά τους. Υποθέστε ότι για την εκτέλεση των αναγκαίων αριθμητικών πράξεων διατίθενται οι εντολές add, sub, mul και div. Δείξτε το περιεχόμενο της στοίβας μετά την εκτέλεση καθεμιάς από τις εντολές του κώδικά σας. Β. Θεωρήστε στη συνέχεια ότι οι εντολές push και pop δέχονται και έμμεση διευθυνσιοδότηση μέσω μνήμης, η οποία στη συμβολική γλώσσα του επεξεργαστή αναγράφεται με παρενθέσεις γύρω από τη διεύθυνση προσπέλασης. Επίσης, θεωρήστε ότι διατίθενται και εντολές διακλάδωσης, έστω beq και bne, οι οποίες εκτελούν άλμα σε περίπτωση μηδενικής ή μη μηδενικής τιμής του στοιχείου στην κορυφή της στοίβας, το οποίο και αφαιρείται από αυτήν. Ο προορισμός του άλματος αναγράφεται ως ετικέτα στον κώδικα συμβολικής γλώσσας του επεξεργαστή, και υλοποιείται με σχετική διευθυνσιοδότηση. Τέλος, θεωρήστε ότι διατίθεται και η εντολή pushi, άμεσης διευθυνσιοδότησης, η οποία εισάγει στην κορυφή της στοίβας μια σταθερά. Γράψτε τώρα το συντομότερο δυνατό κώδικα συμβολικής γλώσσας για την εκτέλεση του βρόχου: FOR I = 1,N Z[I] = A[I]*B C[I]*(D + E[I]/F) ENDFOR όπου τώρα τα A, C, E και Z είναι μεταβλητές που περιέχουν τις αρχικές διευθύνσεις ομώνυμων διανυσμάτων στη μνήμη και Ι, Ν είναι νέες μεταβλητές. Υποθέστε ότι η μνήμη διευθυνσιοδοτείται σε λέξεις ίσου μεγέθους με τα στοιχεία των τεσσάρων διανυσμάτων, και ότι τα διανύσματα δεικτοδοτούνται από 1 έως την τιμή της μεταβλητής Ν. Απάντηση: Α. Για τον υπολογισμό της πιο πάνω έκφρασης σε έναν επεξεργαστή αρχιτεκτονικής στοίβας, πρέπει να φορτώσουμε στη στοίβα τις τιμές των μεταβλητών του δεξιού μέλους της ανάθεσης, να εκτελέσουμε τις απαιτούμενες πράξεις, και στο τέλος να αποθηκεύσουμε το αποτέλε-

7 σμα στη μνήμη. Επομένως μπορούμε εύκολα να βρούμε ότι ο ελάχιστος αριθμός εντολών που θα χρειαστούμε είναι 6 εντολές push, 5 εντολές αριθμητικών πράξεων, και 1 εντολή pop. Για κάθε αριθμητική πράξη που εκτελούμε, τα δύο τελούμενα εισόδου πρέπει να βρίσκονται στην κορυφή της στοίβας. Ενώ για τις πράξεις της πρόσθεσης και του πολλαπλασιασμού μπορούμε να υποθέσουμε ότι δε μας ενδιαφέρει η σειρά που τα τελούμενα αυτά εισάγονται στη στοίβα, για τις πράξεις της αφαίρεσης και της διαίρεσης η σειρά αυτή είναι ουσιαστική για την ορθότητα του αποτελέσματος. Επομένως, για τις δύο τελευταίες πράξεις, πρέπει να εισάγουμε στη στοίβα πρώτα το δεξί και μετά το αριστερό τελούμενό τους. Σε κάθε πράξη, τα τελούμενα εισόδου αφαιρούνται από την κορυφή της στοίβας, ενώ το αποτέλεσμα της πράξης τοποθετείται στη νέα κορυφή της στοίβας. Σε διαδοχικές πράξεις, κάποιο ή και τα δύο από τα τελούμενα εισόδου μιας πράξης είναι δυνατό να βρίσκονται στη στοίβα σαν αποτελέσματα προηγούμενων πράξεων, και όχι ύστερα από αντίστοιχες εντολές φόρτωσης push. Κάτι τέτοιο μάλιστα είναι επιθυμητό στην παρούσα άσκηση, εφ όσον μας ζητείται ο ελάχιστος αριθμός εντολών, κι επομένως θα πρέπει να περιορίσουμε τις εντολές φόρτωσης στις απολύτως αναγκαίες. Αν δε θέλαμε να βρούμε τον ελάχιστο αριθμό εντολών, θα μπορούσαμε να αποθηκεύουμε το αποτέλεσμα κάθε πράξης πλην της τελευταίας σε προσωρινή θέση μνήμης, και να το ξαναφορτώνουμε στη στοίβα, όταν το χρειαζόμαστε σε επόμενη πράξη. Τώρα όμως, πρέπει να φροντίσουμε να εκτελούμε τις διαδοχικές πράξεις με τέτοια σειρά, ώστε τα αποτελέσματά τους να διατίθενται στη στοίβα για τις πράξεις που ακολουθούν 2. Για παράδειγμα, ο δεύτερος από αριστερά πολλαπλασιασμός στην έκφραση που μας δόθηκε μπορεί να εκτελεστεί, μόλις τα δύο τελούμενα εισόδου του τοποθετηθούν στη στοίβα. Το α- ριστερό τελούμενο είναι μια μεταβλητή, που πρέπει να φορτωθεί από τη μνήμη. Το δεξί τελούμενο όμως είναι μια υποέκφραση, που πρέπει να αποτιμηθεί πριν την εκτέλεση του πολλαπλασιασμού. Λόγω της αντιμεταθετικότητας του πολλαπλασιασμού, και σύμφωνα με όσα αναφέραμε πιο πάνω, μπορούμε να φορτώσουμε τη μεταβλητή C στη στοίβα είτε πριν, είτε μετά τον υπολογισμό της υποέκφρασης D+E/F. Για την εκτέλεση του πολλαπλασιασμού, το δεξί τελούμενο αυτού θα βρεθεί στη στοίβα, σαν το αποτέλεσμα της υποέκφρασης αυτής. Ας σημειωθεί ότι ο υπολογισμός κάθε επιμέρους υποέκφρασης πρέπει να γίνεται με μια διαδοχή εντολών που αφορούν μόνο αυτή την υποέκφραση. Για το πιο πάνω παράδειγμα, δε θα μπορούσαμε να παρεμβάλουμε την εντολή φόρτωσης της μεταβλητής C ανάμεσα στις εντολές αποτίμησης της υποέκφρασης D+E/F, διαφορετικά η στοίβα δε θα περιείχε τις τιμές των τελούμενων του πολλαπλασιασμού, αλλά κάποιες άλλες τυχαίες τιμές. Με βάση τα παραπάνω, ένας κώδικας που υπολογίζει την έκφραση Z = A*B - C*(D + E/F) στον επεξεργαστή μας είναι ο ακόλουθος: push C push D push F push E div add mul push A push B mul sub pop Z 2 Αυθαίρετη επιλογή στη σειρά εκτέλεσης διαδοχικών πράξεων δεν είναι πάντα επιτρεπτή. Πολλές φορές, σε γλώσσες προγραμματισμού υψηλού επιπέδου επιβάλλεται αποτίμηση εκφράσεων από αριστερά προς τα δεξιά. Τότε, οι αντίστοιχες πράξεις πρέπει να εκτελούνται από αριστερά προς τα δεξιά, και τα ενδιάμεσα αποτελέσματα αυτών να αποθηκεύονται σε προσωρινές θέσεις μνήμης, αν δε μπορούν να χρησιμοποιηθούν άμεσα. Στην παρούσα άσκηση δεν έχουμε τέτοιον περιορισμό.

Στοίβα Στοίβα 8 Παρατηρήστε ότι για τις δύο πράξεις που δεν έχουν αντιμεταθετικότητα, τοποθετείται στη στοίβα πρώτα το δεξί τελούμενο, και μετά το αριστερό. Για παράδειγμα, για να εκτελεστεί η αφαίρεση, πρώτα αποτιμάται η υποέκφραση C*(D + E/F) και μετά η A*B. Για να δούμε τι περιέχει η στοίβα μετά την εκτέλεση καθεμιάς από τις πιο πάνω εντολές, σχηματίζουμε τον ακόλουθο πίνακα, υποθέτοντας ότι η στοίβα είναι αρχικά άδεια: Εντολή push C push D push F push E div add mul push A push B mul sub pop Z E F F E/F B D D D D D+E/F A A A*B C C C C C C Υ Υ Υ Υ A*B-Υ όπου σε κάθε μη κενή θέση στη στοίβα περιέχεται η τιμή της αντίστοιχης μεταβλητής ή έκφρασης. Στον παραπάνω πίνακα συμβολίσαμε με Υ την υποέκφραση C*(D+E/F). Σαν εναλλακτική απάντηση, ας δώσουμε τον κώδικα που εισάγει στη στοίβα τα τελούμενα εισόδου με την προβλεπόμενη σειρά ακόμα και για τις πράξεις της πρόσθεσης και του πολλαπλασιασμού που δεν έχουν αντιμεταθετικότητα: push F push E div push D add push C mul push Β push Α mul sub pop Z Τέλος, ας δούμε τι περιέχει η στοίβα μετά την εκτέλεση καθεμιάς από τις πιο πάνω εντολές: Εντολή push F push E div push D add push C mul push B push A mul sub pop Z A E D C B B A*B F F E/F E/F D+E/F D+E/F Υ Υ Υ Υ A*B-Υ όπου και πάλι με Υ συμβολίσαμε την υποέκφραση C*(D+E/F). Β. Για το δεύτερο ερώτημα της άσκησης, παρατηρούμε ότι ο κώδικας που υπολογίζεται σε κάθε επανάληψη του βρόχου μοιάζει με τον κώδικα του προηγούμενου ερωτήματος. Άρα θα χρειαστούμε τον ίδιο ελάχιστο αριθμό εντολών ανά επανάληψη, με τη διαφορά ότι θα χρειαστούμε επιπλέον (α) κώδικα υπολογισμού της διεύθυνσης των στοιχείων των διανυσμάτων που προσπελαύνονται, και (β) κώδικα ελέγχου του βρόχου. Με βάση την εκφώνηση, κι εφόσον τα Α, C, E και Z περιέχουν τις αρχικές διευθύνσεις των ομώνυμων διανυσμάτων, και το μέγεθος στοιχείου του κάθε διανύσματος είναι ίσο με το μέγεθος λέξης μνήμης, ο υπολογισμός της διεύθυνσης ενός στοιχείου, έστω του A[I], θα γίνεται με φόρτωση του περιεχομένου του Α, με φόρτωση του περιεχομένου του Ι, και πρόσθεση των

9 δύο τιμών, δηλαδή της αρχικής διεύθυνσης του διανύσματος Α και του δείκτη Ι, με την προϋπόθεση ότι προσαρμόζουμε το δείκτη να μεταβάλλεται από 0, ώστε το στοιχείο Α[1] να αντιστοιχείται στη διεύθυνση Α+0. Επειδή μας διατίθεται μόνο κατ ευθείαν και έμμεση διευθυνσιοδότηση μνήμης, ο μοναδικός τρόπος να λάβουμε την τιμή ενός στοιχείου διανύσματος είναι να αποθηκεύσουμε την υπολογισμένη διεύθυνση σε κάποια βοηθητική θέση μνήμης, και στη συνέχεια να φορτώσουμε με έμμεση διευθυνσιοδότηση από αυτή τη διεύθυνση. Έτσι, για τη φόρτωση στη στοίβα του στοιχείου Α[Ι] θα χρειαστούμε τον κώδικα: push A push I add pop T push (T) όπου Τ κάποια διεύθυνση μνήμης. Παρόμοια και για τα υπόλοιπα στοιχεία διανυσμάτων. Όσο αφορά τον κώδικα ελέγχου του βρόχου, επειδή διατίθενται οι εντολές beq και bne που συγκρίνουν με μηδενική τιμή, θα αντιστρέψουμε τη σειρά των επαναλήψεων, και θα μεταβάλλουμε το δείκτη από Ν-1 μέχρι το 0. Έτσι, θα αρχικοποιήσουμε το Ι με την τιμή Ν, και στο τέλος κάθε επανάληψης θα φορτώνουμε στην κορυφή της στοίβας το Ι για να το χρησιμοποιήσουμε σε εντολή bne με προορισμό την αρχή του βρόχου. Η μείωση του Ι θα γίνεται στην αρχή της κάθε επανάληψης του βρόχου. Ο τελικός κώδικας, με βάση τον πρώτο από τους δύο κώδικες του ερωτήματος Α, θα είναι: push N pop I ; I = N Loop: pushi 1 push I sub pop I ; I = I-1 push C push I add pop T ; T = &C[I] push (T) ; push C[I] push D push F push E push I add pop T ; T = &E[I] push (T) ; push E[I] div ; E[I]/F add ; D+E[I]/F mul ; C[I]*(D+E[I]/F) push A push I add pop T ; T = &A[I] push (T) ; push A[I] push B mul ; A[I]*B sub ; A[I]*B-C[I]*(D+E[I]/F) push Z push I add pop T ; T = &Z[I] pop (T) ; Z[I] = A[I]*B-C[I]*(D+E[I]/F) push I bne Loop ; if I!=0 goto Loop

10 όπου με μορφή σχολίων δίνουμε το αποτέλεσμα των κυριότερων εντολών. Παρατηρήστε ότι στον πιο πάνω κώδικα πολλές προσπελάσεις μνήμης επαναλαμβάνονται, όπως για παράδειγμα η φόρτωση του Ι, η οποία επαναλαμβάνεται 6 φορές στην ίδια επανάληψη του βρόχου. Άλλες προσπελάσεις μνήμης επαναλαμβάνονται σε διαδοχικές επαναλήψεις του βρόχου, όπως για παράδειγμα οι φορτώσεις των βαθμωτών μεταβλητών Β, D και F, αλλά και των αρχικών διευθύνσεων των διανυσμάτων A, C, E και Z. Η αύξηση των προσπελάσεων μνήμης έχει σαν αποτέλεσμα τη μειωμένη απόδοση του κώδικα. Ένας τρόπος αντιμετώπισης του προβλήματος αυτού είναι η εισαγωγή στο σύνολο εντολών του επεξεργαστή α- ριθμητικών εντολών που δεν αφαιρούν κατ ανάγκη τα τελούμενά τους από τη στοίβα. Με τέτοιες εντολές μπορούμε να διατηρούμε στη στοίβα τιμές που χρησιμοποιούμε συχνά, είτε στην ίδια, είτε σε διαδοχικές επαναλήψεις του βρόχου, μειώνοντας έτσι το κόστος προσπελάσεων μνήμης και το συνολικό χρόνο εκτέλεσης του κώδικα, δεδομένου ότι το κόστος προσπελάσεων της στοίβας είναι πολύ μικρότερο από εκείνο της μνήμης. Άσκηση 6: Έστω μια αρχιτεκτονική επέκτασης συσσωρευτή, με ένα συσσωρευτή Σ και δύο καταχωρητέςδείκτες X και Y. Οι εντολές της αρχιτεκτονικής αυτής είναι οι: Load (φόρτωσε τον Σ), Store (αποθήκευσε από τον Σ), Add (πρόσθεσε στον Σ), Sub (αφαίρεσε από τον Σ), Cmp (σύγκρινε με τον Σ για ισότητα), Beqz (εκτέλεσε άλμα αν ο Σ έχει μηδενική τιμή), LdX, LdY (φόρτωσε τον Χ ή τον Υ), StX, StY (αποθήκευσε από τον Χ ή από τον Υ), IncX, IncY (αύξησε τον Χ ή τον Υ), CmpX, CmpY (σύγκρινε με τον Χ ή με τον Υ για ισότητα), Beq, Bne (εκτέλεσε άλμα αν η τελευταία σύγκριση ήταν αληθής ή ψευδής) και Jmp (εκτέλεσε άλμα). Οι εντολές σύγκρισης Cmp, CmpX και CmpY γράφουν το αποτέλεσμά τους σε ειδικό ψηφίο ε- λέγχου του επεξεργαστή, το οποίο χρησιμοποιείται μόνο από τις εντολές διακλάδωσης Beq και Bne. Η παραπάνω αρχιτεκτονική υποστηρίζει τις εξής μεθόδους διευθυνσιοδότησης της μνήμης: Κατ' ευθείαν (με διεύθυνση μνήμης), έμμεση (με διεύθυνση που βρίσκεται σε κάποια διεύθυνση μνήμης), δεικτοδοτούμενη μέσω του Χ ή του Υ (με διεύθυνση που προστίθεται με τον Χ ή τον Υ), δεικτοδοτούμενη μέσω του Χ και έμμεση (πρώτα δεικτοδοτούμενη μέσω του Χ και ύστερα έμμεση), έμμεση και δεικτοδοτούμενη μέσω του Υ (πρώτα έμμεση και ύστερα δεικτοδοτούμενη μέσω του Υ), και τέλος δεικτοδοτούμενη μέσω του Χ, έμμεση και δεικτοδοτούμενη μέσω του Υ (πρώτα δεικτοδοτούμενη μέσω του Χ, ύστερα έμμεση και τέλος δεικτοδοτούμενη μέσω του Υ). Από τις εντολές της αρχιτεκτονικής, μόνο οι πέντε πρώτες και η εντολή Jmp δέχονται όλες τις πιο πάνω μεθόδους διευθυνσιοδότησης της μνήμης. Οι εντολές που αναφέρονται στους καταχωρητές Χ και Υ, εκτός των εντολών IncX και IncY που δεν έχουν τελούμενο, δέχονται κατ' ευθείαν και έμμεση διευθυνσιοδότηση. Οι εντολές Beqz, Beq και Bne δέχονται σχετική διευθυνσιοδότηση με μετατόπιση σχετικά με το μετρητή προγράμματος. Τέλος, οι εντολές Load, LdX και LdY, όπως και οι εντολές Add, Sub, Cmp, CmpX και CmpY δέχονται και άμεσο τελούμενο. Για την παραπάνω αρχιτεκτονική γράψτε ένα πρόγραμμα σε συμβολική γλώσσα που μεταφέρει τους χαρακτήρες ενός πίνακα από ορμαθούς χαρακτήρων (strings) σε κάποιο συνεχόμενο χώρο μνήμης. Ο πίνακας περιέχει τις διευθύνσεις στις οποίες αρχίζουν οι ορμαθοί και οι οποίες είναι τυχαία διασπαρμένες στη μνήμη, ξεκινά σε κάποια διεύθυνση μνήμης Α και τερματίζεται μετά από Μ ορμαθούς, όπου Μ κάποια σταθερά, ή μόλις συναντηθεί μηδενική διεύθυνση. Κάθε ορμαθός τερματίζεται με το μηδενικό χαρακτήρα, στη θέση του οποίου μεταφέρεται ο χαρακτήρας αλλαγής γραμμής \n. Ο συνεχόμενος χώρος στη μνήμη ξεκινά σε κάποια διεύθυνση Β, και χωράει μέχρι Ν χαρακτήρες, όπου Ν κάποια άλλη σταθερά. Ο αριθμός των χαρακτήρων που μεταφέρθηκαν πρέπει να αποθηκευτεί σε κάποια διεύθυνση Κ. Θεωρήστε ότι η μνήμη διευθυνσιοδοτείται σε ψηφιολέξεις (bytes), κάθε χαρακτήρας καταλαμβάνει μια ψηφιολέξη, ενώ κάθε διεύθυνση καταλαμβάνει τέσσερις ψηφιολέξεις. Υποθέστε ότι οι σταθερές Μ και Ν είναι μη μηδενικές.

11 Απάντηση: Έστω ότι η συμβολική γλώσσα της αρχιτεκτονικής μας υποστηρίζει τον ακόλουθο συμβολισμό για αναφορά σε άμεσο τελούμενο (ενδεικτικά για την εντολή Load): - Αριθμητική σταθερά: Load #Ν - Χαρακτήρας ASCII: Load a Έστω ακόμα ότι έχουμε τον ακόλουθο συμβολισμό για τη διευθυνσιοδότηση της μνήμης (ενδεικτικά για την εντολή Load, για κάποια διεύθυνση μνήμης Δ): - Κατ' ευθείαν: Load Δ - Έμμεση: Load (Δ) - Δεικτοδοτούμενη μέσω του Χ: Load Δ,X - Δεικτοδοτούμενη μέσω του Χ και έμμεση: Load (Δ,Χ) - Έμμεση και δεικτοδοτούμενη μέσω του Υ: Load (Δ),Υ - Δεικτοδοτούμενη μέσω του Χ, έμμεση και δεικτοδοτούμενη μέσω του Υ: Load (Δ,Χ),Υ Υπενθυμίζουμε ότι η επίλυση αναφοράς (δηλαδή ο υπολογισμός της τελικής διεύθυνσης μνήμης στην οποία αναφέρεται μια εντολή) στην περίπτωση έμμεσης διευθυνσιοδότησης γίνεται με φόρτωση της τελικής διεύθυνσης από τη μνήμη, από τη διεύθυνση που δίνεται στην εντολή, ενώ στην περίπτωση δεικτοδοτούμενης διευθυνσιοδότησης γίνεται με πρόσθεση της τιμής του καταχωρητή δείκτη στη διεύθυνση που δίνεται στην εντολή. Οι συνδυασμοί έμμεσης και δεικτοδοτούμενης διευθυνσιοδότησης απαιτούν αντίστοιχο συνδυασμό μικρολειτουργιών για την επίλυση αναφοράς. Για παράδειγμα, στην αρχιτεκτονική που μας δίνεται, η τελευταία μέθοδος διευθυνσιοδότησης απαιτεί πρώτα μια πρόσθεση της τιμής του Χ στη διεύθυνση που δίνεται στην εντολή, στη συνέχεια φόρτωση μιας νέας διεύθυνσης από τη μνήμη, από τη διεύθυνση που υπολογίστηκε, και τέλος νέα πρόσθεση, της τιμής του Υ αυτή τη φορά, στη διεύθυνση που φορτώθηκε. Αλγεβρικά, αν MEM είναι μονοδιάστατος πίνακας που απεικονίζει τη μνήμη, τότε η τελική διεύθυνση προσπέλασης για καθεμία από τις διευθυνσιοδοτήσεις θα είναι: Δ, ΜΕΜ[Δ], Δ+Χ, ΜΕΜ[Δ+Χ], ΜΕΜ[Δ]+Υ, ΜΕΜ[Δ+Χ]+Υ, με τη σειρά που τις δώσαμε παραπάνω. Σε κάθε μέθοδο διευθυνσιοδότησης, η τελική διεύθυνση μνήμης χρησιμοποιείται ανάλογα με την εντολή. Αν για παράδειγμα η εντολή είναι εντολή φόρτωσης, η διεύθυνση αυτή στέλνεται στη μνήμη για τη φόρτωση κάποιου δεδομένου, ενώ αν είναι εντολή άλματος, η διεύθυνση αυτή στέλνεται στο μετρητή προγράμματος. Ο κώδικας που θέλουμε να γράψουμε στην παρούσα άσκηση μεταφέρει δεδομένα από μια δομή σε κάποια άλλη. Σε μορφή γλώσσας C η πρώτη δομή, η Α, είναι δηλωμένη ως: char * A[M]; και η δεύτερη, η Β, ως: char B[N]; Επομένως ο κώδικάς μας θα πρέπει να διατρέχει την πρώτη δομή, τόσο κατά μήκος του πίνακα Α, όσο και κατά μήκος των ορμαθών (strings) που αυτός έμμεσα περιέχει. Η δεύτερη δομή διατρέχεται κατά μήκος του πίνακα Β. Για να διαβάσουμε τους αποθηκευμένους χαρακτήρες της πρώτης δομής, χρειαζόμαστε ένα διπλό βρόχο, στον οποίο η πρώτη μεταβλητή δείκτης αποτελεί δείκτη στον πίνακα Α, και η δεύτερη μεταβλητή δείκτης αποτελεί δείκτη σε κάθε επιμέρους ορμαθό. Έτσι, η κεντρική λειτουργία που θέλουμε να υλοποιήσουμε μπορεί να γραφτεί ως: B[k] = *(A[i]+j) ή αλλιώς: *(B+k) = *(*(A+i)+j) όπου ο δείκτης i αναφέρεται στον πίνακα Α, ο δείκτης k αναφέρεται στον πίνακα Β, ενώ ο δείκτης j αναφέρεται στον ορμαθό χαρακτήρων που αρχίζει στη διεύθυνση A[i]. Επειδή η ανάγνωση ενός χαρακτήρα γίνεται με πρόσθεση του δείκτη i με τη διεύθυνση βάσης Α, ανάγνωση της διεύθυνσης του αντίστοιχου ορμαθού, πρόσθεση του δείκτη j στη διεύθυνση που διαβάστηκε, και τελική ανάγνωση από τη διεύθυνση που υπολογίσαμε, διαπιστώνου-

12 με ότι η τελευταία από τις μεθόδους διευθυνσιοδότησης που υποστηρίζει η αρχιτεκτονική μας είναι η ιδανική για την ανάγνωση αυτή, με χρήση του καταχωρητή X για τον i, και του καταχωρητή Υ για τον j. Για την αποθήκευση των χαρακτήρων στη δεύτερη δομή, αρκεί απλή δεικτοδοτούμενη διευθυνσιοδότηση, με την πρόσθεση του δείκτη k στη διεύθυνση βάσης Β. Παρατηρούμε μάλιστα ότι ο δείκτης k μας δίνει και τον αριθμό χαρακτήρων που μεταφέρονται. Επομένως, δε χρειάζεται ξεχωριστός υπολογισμός για το σκοπό αυτό. Για να υλοποιήσουμε τον κώδικα σύμφωνα με τα παραπάνω, παρατηρούμε ακόμα τα εξής: - Οι δομές που έχουμε απαιτούν συνολικά τρεις δείκτες, ενώ η αρχιτεκτονική μας παρέχει δύο καταχωρητές. Θα πρέπει έτσι να επιλέξουμε έναν από τους δύο καταχωρητές Χ και Υ να υλοποιεί δύο δείκτες, το οποίο σημαίνει ότι οι τιμές αυτών των δεικτών θα πρέπει να αποθηκεύονται προσωρινά, ώστε οι ρόλοι τους να εναλλάσσονται. Εφ όσον και οι τρεις δείκτες του κώδικα χρησιμοποιούνται σε κάθε επανάληψη του διπλού βρόχου, δεν έχει σημασία ποιοι δύο δείκτες θα εναλλάσσονται. Επειδή ο δείκτης στον πίνακα Β θέλουμε ούτως ή άλλως να αποθηκεύεται στη διεύθυνση Κ, ώστε αυτή να περιέχει τον αριθμό χαρακτήρων που έχουν μεταφερθεί σε κάθε επανάληψη, θα εναλλάσσουμε αυτόν με έναν από τους άλλους δύο, έστω το δείκτη στον πίνακα Α. Ο καταχωρητής που θα χρησιμοποιήσουμε για τους δύο δείκτες θα είναι ο Χ, μια που η διευθυνσιοδότηση για την ανάγνωση των χαρακτήρων επιβάλλει αυτόν τον καταχωρητή για την πρώτη δεικτοδότηση. Υποθέτουμε ότι η προσωρινή αποθήκευση του δείκτη στον πίνακα Α θα γίνεται στη διεύθυνση I. - Πριν γίνει η ανάγνωση του πρώτου χαρακτήρα κάθε ορμαθού, διαβάζεται η διεύθυνση του ορμαθού, ώστε να εξεταστεί αν αυτή είναι μηδενική, οπότε ο κώδικας θα πρέπει να τερματίζεται. Η ανάγνωση της διεύθυνσης γίνεται με απλή δεικτοδοτούμενη διευθυνσιοδότηση, στην οποία θα συμμετέχουν η διεύθυνση Α και ο καταχωρητής Χ. - Η διαδοχική ανάγνωση χαρακτήρων από έναν ορμαθό και αντίστοιχη αποθήκευση στον πίνακα Β τερματίζεται με μηδενικό χαρακτήρα. Επειδή ο μηδενικός χαρακτήρας αποθηκεύεται ως χαρακτήρας αλλαγής γραμμής, ο έλεγχος θα γίνεται πριν την αποθήκευση, ώστε ο κώδικας να εκτελεί άλμα σε σημείο που φορτώνει στο συσσωρευτή το χαρακτήρα \n, πριν κάνει την αποθήκευση. Μετά την αποθήκευση του χαρακτήρα αυτού, ο εσωτερικός βρόχος τερματίζεται. - Εφ όσον οι σταθερές Μ και Ν είναι μη μηδενικές, ο έλεγχος των δεικτών με αυτές τις τιμές μπορεί να γίνεται στο τέλος των βρόχων. Αν ένας από τους δείκτες λάβει την αντίστοιχη οριακή τιμή, ο κώδικας τερματίζεται. Ειδικότερα, για τη σταθερά Μ που αναφέρεται στον πίνακα Α, η οριακή τιμή που θα χρησιμοποιήσουμε θα είναι η 4*Μ, συμβολικά Μ4, επειδή η μετάβαση από ένα στοιχείο του Α στο επόμενο γίνεται με αύξηση του δείκτη κατά 4, λόγω του μεγέθους που έχουν οι διευθύνσεις στην αρχιτεκτονική μας. Με βάση τα παραπάνω, ο ζητούμενος κώδικας δίνεται στην επόμενη σελίδα. Τελειώνοντας, αξίζει να σημειωθεί ότι αν γράφαμε τον ίδιο κώδικα για μια αρχιτεκτονική RISC, όπως για παράδειγμα την αρχιτεκτονική φόρτωσης-αποθήκευσης MIPS, θα προέκυπταν από τη μία περισσότερες εντολές για την προσπέλαση των πινάκων και των ορμαθών, επειδή θα είχαμε απλούστερη διευθυνσιοδότηση μνήμης κι επομένως πολλαπλές εντολές RISC για κάθε προσπέλαση με συνδυασμένη έμμεση και δεικτοδοτούμενη διευθυνσιοδότηση, αλλά από την άλλη λιγότερες συνολικές προσπελάσεις μνήμης, επειδή θα είχαμε καταχωρητές για προσωρινή αποθήκευση των δεικτών που τώρα αποθηκεύουμε στη μνήμη. Έτσι, παρά το ίσως μικρότερο μέγεθός του, ένας κώδικας CISC όπως ο κώδικας αρχιτεκτονικής συσσωρευτή καταλήγει να είναι αρκετά πιο αργός από τον ίδιο κώδικα RISC, πρώτον επειδή οι εντολές RISC είναι απλούστερες, ομοιόμορφες, και εκτελούνται γρηγορότερα, αλλά και δεύτερον επειδή η εκτενής χρήση καταχωρητών γενικού σκοπού μειώνει σημαντικά τον α- ριθμό προσπελάσεων μνήμης, οι οποίες αποτελούν τη σημαντικότερη επιβάρυνση στο χρόνο εκτέλεσης του κώδικα.

13 Κώδικας Load #0 Store Κ LdX #0 Loop1: Load A,X Beqz End1 LdY #0 Loop2: Load (A,X),Y StX I LdX Κ Beqz End2 Store B,X IncX StX Κ CmpX #N Beq End1 LdX I IncY Jmp Loop2 End2: Load \n Store B,X IncX StX Κ CmpX #N Beq End1 LdX I IncX IncX IncX IncX CmpX #M4 Bne Loop1 End1: Σχόλια Αρχικοποίηση του Κ Ανάγνωση διεύθυνσης από τον πίνακα Α Έλεγχος μηδενικής τιμής και τερματισμός Ανάγνωση χαρακτήρα Προσωρινή αποθήκευση του Χ Φόρτωση του Κ στον Χ Έλεγχος μηδενικού χαρακτήρα με κατάλληλο άλμα Αποθήκευση χαρακτήρα στον πίνακα Β Αύξηση κατά 1 του δείκτη στον πίνακα Β Αποθήκευση του Χ στο Κ Σύγκριση του Χ με τη σταθερά Ν Σε περίπτωση ισότητας, τερματισμός Επαναφορά της αποθηκευμένης τιμής του Χ Αύξηση κατά 1 του δείκτη στον ορμαθό Επόμενη επανάληψη του εσωτερικού βρόχου Φόρτωση στον Σ του χαρακτήρα \n Αποθήκευση χαρακτήρα στον πίνακα Β Αύξηση κατά 1 του δείκτη στον πίνακα Β Αποθήκευση του Χ στο Κ Σύγκριση του Χ με τη σταθερά Ν Σε περίπτωση ισότητας, τερματισμός Επαναφορά της αποθηκευμένης τιμής του Χ Αύξηση κατά 4 του δείκτη στον πίνακα Α Σύγκριση του Χ με τη σταθερά Μ4 Σε περίπτωση ανισότητας, επόμενη επανάληψη Άσκηση 7: Θεωρήστε τη συμβολική γλώσσα της αρχιτεκτονικής φόρτωσης-αποθήκευσης MIPS. Υποθέστε ότι ο καταχωρητής $sp περιέχει το δείκτη στη στοίβα κι ότι ο καταχωρητής $ra αποθηκεύει τη διεύθυνση επανόδου από υποπρόγραμμα 3. Ακόμα υποθέστε ότι οι καταχωρητές $4-7 χρησιμοποιούνται για το πέρασμα παραμέτρων σε υποπρόγραμμα κι ότι οι καταχωρητές $16-23 πρέπει να διατηρούν το περιεχόμενό τους κατά την κλήση υποπρογράμματος. Γράψτε τον κώδικα συμβολικής γλώσσας που υλοποιεί τον παρακάτω κώδικα C: sort (int v[], int n) { int i, j; for (i = 0; i < n; i = i+1) { for (j = i-1; j >= 0 && v[j] > v[j+1]; j = j-1) swap(v, j); } } 3 $sp και $ra είναι τα συμβολικά ονόματα των καταχωρητών $29 και $31 αντίστοιχα.

14 Απάντηση: Στην άσκηση αυτή θέλουμε να βρούμε τον κώδικα συμβολικής γλώσσας της αρχιτεκτονικής MIPS που υλοποιεί το υποπρόγραμμα sort το οποίο καλεί ένα άλλο υποπρόγραμμα swap. Κάθε φορά που ξεκινάμε ένα υποπρόγραμμα, είναι πιθανό να χρειαστεί να προσπελάσουμε τη στοίβα για αποθήκευση δεδομένων από καταχωρητές που θέλουμε να χρησιμοποιήσουμε σε αυτό. Για παράδειγμα, αν θέλουμε να χρησιμοποιήσουμε έναν από τους καταχωρητές $16-23, το περιεχόμενο των οποίων πρέπει να διατηρείται κατά την κλήση του υποπρογράμματος, πρέπει να ξεκινήσουμε το υποπρόγραμμα με αποθήκευση της τιμής του στη στοίβα. Πριν την έξοδο από το υποπρόγραμμα, επαναφέρουμε την τιμή αυτή πίσω στον καταχωρητή. Γενικά, χρησιμοποιούμε τη στοίβα για προσωρινή αποθήκευση δεδομένων που δε μπορούμε να διατηρούμε σε καταχωρητές. Ο συνολικός χώρος που κάποιο υποπρόγραμμα καταλαμβάνει στη στοίβα πρέπει να λαμβάνεται υπ όψη, εάν αυτό καλεί άλλο υποπρόγραμμα. Πριν από μια φωλιασμένη κλήση, είναι απαραίτητο να διορθώσουμε τον καταχωρητή $sp κατάλληλα, ώστε να δείχνει στην επόμενη ελεύθερη διεύθυνση της στοίβας. Βέβαια, δε μπορούμε να γράψουμε τον κώδικα που υλοποιεί τα παραπάνω, πριν αποκτήσουμε μια καθολική εικόνα του υποπρογράμματος, ώστε να ξέρουμε πόσες και ποιες τιμές πρέπει να αποθηκευτούν στη στοίβα, γι αυτό και συνεχίζουμε με το σώμα του, κι αφήνουμε για το τέλος την προσθήκη όποιων εντολών αναφέρονται στη στοίβα. Το υποπρόγραμμα sort χρησιμοποιεί δύο παραμέτρους, οι οποίες με το ξεκίνημα του υποπρογράμματος βρίσκονται στους καταχωρητές $4 και $5. Έτσι ο πρώτος από τους δύο καταχωρητές περιέχει τη διεύθυνση στη μνήμη όπου αρχίζει το διάνυσμα v, ενώ ο δεύτερος περιέχει την τιμή του n. Ακόμα, το υποπρόγραμμα sort χρησιμοποιεί δύο τοπικές μεταβλητές που επιλέγουμε να τοποθετήσουμε στους καταχωρητές $16 και $17. Αρχίζουμε με τον εξωτερικό βρόχο που αντιστοιχεί στην πρώτη εντολή for. Η αρχικοποίηση της μεταβλητής i γίνεται με την εντολή: move 4 $16, $0 Υπενθυμίζεται ότι ο καταχωρητής $0 περιέχει μόνιμα την τιμή 0. Στη συνέχεια θα πρέπει να εισάγουμε τον κώδικα ελέγχου τερματισμού του βρόχου, και στο τέλος του σώματος του βρόχου τον κώδικα αύξησης του i, καθώς και μια εντολή άλματος προς την αρχή του σώματος του βρόχου: For1: slt $8, $16, $5 beq $8, $0, Exit1 addi $16, $16, 1 j For1 Exit1: Ο καταχωρητής $8 χρησιμοποιείται σαν προσωρινός χώρος αποθήκευσης του αποτελέσματος της σύγκρισης του i με το n. Με παρόμοιο τρόπο εισάγουμε στο σώμα του εξωτερικού βρόχου τις εντολές ελέγχου του εσωτερικού βρόχου. Τώρα όμως η συνθήκη τερματισμού του βρόχου δεν είναι απλή. Επειδή όμως αυτή βρίσκεται με ένα λογικό γινόμενο, μπορούμε ισοδύναμα να ελέγξουμε τον πρώτο όρο του γινομένου, κι αν αυτός δεν έχει τιμή 1 (αληθής), τότε εκτελούμε άλμα στην έξοδο 4 Η εντολή move είναι ψευδοεντολή, δηλαδή δεν αντιστοιχεί σε πραγματική εντολή της γλώσσας μηχανής της αρχιτεκτονικής MIPS, και χρησιμοποιείται αντί του λιγότερο προφανούς: ori $16, $0, 0 που έχει το ίδιο ακριβώς αποτέλεσμα. Η χρήση ψευδοεντολών διευκολύνει τη συγγραφή προγραμμάτων σε συμβολική γλώσσα, εάν υποστηρίζεται από το συμβολομεταφραστή που θα μετατρέψει το πρόγραμμα σε γλώσσα μηχανής. Κάθε ψευδοεντολή πρέπει να είναι πλήρως ορισμένη όταν χρησιμοποιείται.

15 του βρόχου. Στη συνέχεια ελέγχουμε το δεύτερο όρο του γινομένου κι αντίστοιχα εισάγουμε μια εντολή άλματος υπό τη συνθήκη ότι αυτός δεν έχει τιμή 1 (αληθής). Για να ελέγξουμε το δεύτερο όρο, διαβάζουμε από τη μνήμη τις μεταβλητές v[j] και v[j+1], χρησιμοποιώντας σα διεύθυνση προσπέλασης το άθροισμα της αρχικής διεύθυνσης του διανύσματος με την τιμή του j πολλαπλασιασμένη επί 4. Η δεύτερη μεταβλητή διαβάζεται με την ίδια διεύθυνση προσπέλασης, μετατοπισμένη κατά 4. Έτσι ο κώδικας ελέγχου του εσωτερικού βρόχου είναι: addi $17, $16, -1 For2: slt $8, $17, $0 bne $8, $0, Exit2 sll $9, $17, 2 add $10, $4, $9 lw $11, 0($10) lw $12, 4($10) slt $8, $12, $11 beq $8, $0, Exit2 addi $17, $17, -1 j For2 Exit2: Το σώμα του εσωτερικού βρόχου περιέχει μόνο την κλήση του υποπρογράμματος swap. Για να γράψουμε τον κώδικα της κλήσης πρέπει να περάσουμε τις αντίστοιχες παραμέτρους στο υποπρόγραμμα. Όμως, επειδή οι παράμετροι περνάνε πάντα μέσω των καταχωρητών $4-7, θα πρέπει να σώσουμε τις τιμές των $4 και $5 που χρησιμοποιούμε στο υποπρόγραμμα sort. Για το σκοπό αυτό χρησιμοποιούμε δύο ακόμα καταχωρητές (αντί για θέσεις μνήμης στη στοίβα που επίσης θα μπορούσαμε να χρησιμοποιήσουμε), τους $18 και $19. Αντί δε να σώσουμε τις τιμές πριν από την κλήση και μετά να τις επαναφέρουμε, είναι καλύτερα να τις σώσουμε στην αρχή του sort, και να χρησιμοποιούμε τους καταχωρητές $18 και $19 εκεί που μέχρι τώρα χρησιμοποιήσαμε τους $4 και $5. Η κλήση στο υποπρόγραμμα swap θα γίνει ως εξής: move $4, $18 move $5, $17 jal swap Τελειώσαμε έτσι με το σώμα του υποπρογράμματος sort. Γυρνώντας πάλι στην αρχή του κώδικα, βλέπουμε ότι έχουμε χρησιμοποιήσει 4 από τους καταχωρητές $16-23, την αρχική τιμή των οποίων πρέπει να σώσουμε στη στοίβα, και στο τέλος να την επαναφέρουμε, ώστε να είναι πάλι διαθέσιμη με την έξοδο από το sort. Επίσης, με την κλήση του swap χάνουμε την αρχική τιμή του $ra, που χρειαζόμαστε απαραιτήτως για την έξοδο από το sort. Επομένως, πρέπει να σώσουμε τις τιμές συνολικά 5 καταχωρητών στη στοίβα, γι αυτό και θα μειώσουμε και στο τέλος θα αυξήσουμε την τιμή του δείκτη στοίβας $sp κατά 5 λέξεις (20 bytes). Ο συνολικός κώδικας του υποπρογράμματος sort δίνεται στην επόμενη σελίδα.

16 Κώδικας Περιγραφή sort: addi $sp, $sp, -20 η στοίβα αυξάνεται προς τα κάτω! sw $ra, 16($sp) αποθήκευσε τον $ra στη θέση $sp+16 sw $19, 12($sp) αποθήκευσε τον $19 στη θέση $sp+12 sw $18, 8($sp) αποθήκευσε τον $18 στη θέση $sp+8 sw $17, 4($sp) αποθήκευσε τον $17 στη θέση $sp+4 sw $16, 0($sp) αποθήκευσε τον $16 στη θέση $sp+0 move $18, $4 σώσε το περιεχόμενο του $4 στον $18 move $19, $5 σώσε το περιεχόμενο του $5 στον $19 move $16, $0 i = 0 For1: slt $8, $16, $19 $8 = i < n beq $8, $0, Exit1 if not $8 goto Exit1 addi $17, $16, -1 j = i - 1 For2: slt $8, $17, $0 $8 = j < 0 bne $8, $0, Exit2 if $8 goto Exit2 sll $9, $17, 2 $9 = j * 4 add $10, $18, $9 $10 = διεύθυνση (v[j]) lw $11, 0($10) $11 = v[j] lw $12, 4($10) $12 = v[j+1] slt $8, $12, $11 $8 = v[j] > v[j+1] beq $8, $0, Exit2 if not $8 goto Exit2 move $4, $18 1η παράμετρος του swap move $5, $17 2η παράμετρος του swap jal swap κάλεσε το swap, $ra = διεύθυνση επανόδου addi $17, $17, -1 j = j - 1 j For2 goto For2 Exit2: addi $16, $16, 1 i = i + 1 j For1 goto For1 Exit1: lw $16, 0($sp) φόρτωσε τον $16 lw $17, 4($sp) φόρτωσε τον $17 lw $18, 8($sp) φόρτωσε τον $18 lw $19, 12($sp) φόρτωσε τον $19 lw $ra, 16($sp) φόρτωσε τον $ra addi $sp, $sp, 20 επανάφερε τον $sp στην αρχική του τιμή jr $ra επέστρεψε! Άσκηση 8: Θεωρήστε τον πιο κάτω κώδικα δύο συναρτήσεων σε γλώσσα C, από τις οποίες η πρώτη καλεί τη δεύτερη, και η δεύτερη καλεί αναδρομικά τον εαυτό της: int foo1 (int n, char* a, int** x) { int i, y; y = 0; for (i = 0; i < n; i++) { if (a[i] == '\0') y += foo2(i, x[i]); else y++; } return y; } int foo2 (int n, int* l) { if (n > 0) return l[foo2(n-1, l+1)]; else return l[0]; }

17 Α. Παρατηρώντας τον κώδικα στη γλώσσα C, εξηγήστε ποιες μεταβλητές της κάθε συνάρτησης πρέπει να διατηρούν την τιμή τους μέσα από την κλήση υποπρογράμματος που υπάρχει στο σώμα της συνάρτησης. Β. Να μετατρέψετε τον κώδικα σε συμβολική γλώσσα αρχιτεκτονικής MIPS. Υποθέστε ότι ο καταχωρητής $sp περιέχει το δείκτη στη στοίβα κι ότι ο καταχωρητής $ra αποθηκεύει τη διεύθυνση επανόδου από υποπρόγραμμα. Ακόμα υποθέστε ότι οι καταχωρητές $a0-a3 χρησιμοποιούνται για το πέρασμα των παραμέτρων στις συναρτήσεις κι ότι οι καταχωρητές $s0-s8 πρέπει να διατηρούν το περιεχόμενό τους κατά την κλήση ενός υποπρογράμματος. Οι καταχωρητές γενικού σκοπού που δεν είναι απαραίτητο να διατηρούν το περιεχόμενό τους μέσα από ένα υποπρόγραμμα αναφέρονται συμβολικά ως $t0-t9. Ο καταχωρητής που επιστρέφει την τιμή μιας συνάρτησης στο καλούν περιβάλλον είναι ο $v0 5. Γ. Έχοντας εξασφαλίσει τη διατήρηση των περιεχομένων των καταχωρητών που χρειάζεστε μέσα από τις κλήσεις των συναρτήσεων foo1 και foo2, δείξτε σχηματικά τη μορφή της στοίβας από τη θέση που δείχνει ο $sp τη στιγμή της κλήσης της foo1 μέχρι τη θέση που δείχνει ο $sp τη στιγμή δεύτερης εξόδου από τη foo2 μετά από την κλήση της foo1. Το στιγμιότυπο της στοίβας λαμβάνεται την παραπάνω στιγμή εξόδου από την foo2. Υποθέστε ότι η συνθήκη (a[i] == '\0') είναι για πρώτη φορά αληθής όταν ο δείκτης i έχει τιμή 5. Δ. Εξηγήστε τι θα συμβεί κατά την εκτέλεση του κώδικά σας, εάν δε διατηρήσετε την τιμή του $ra (i) στον κώδικα της foo1 μέσα από την κλήση της foo2, και (ii) στον κώδικα της foo2 μέσα από την αναδρομική κλήση του εαυτού της. Απάντηση: Α. Η συνάρτηση foo1 περιέχει 5 μεταβλητές, από τις οποίες οι 3 είναι οι παράμετροί της n, a και x, ενώ οι υπόλοιπες 2 είναι οι i και y. Το σώμα της συνάρτησης αυτής περιέχει ένα βρόχο, στο σώμα του οποίου υπάρχει κλήση στην foo2. Παρατηρούμε ότι κάθε επανάληψη του βρόχου χρειάζεται και τις 5 μεταβλητές: Η παράμετρος n είναι απαραίτητη για τον έλεγχο τερματισμού του βρόχου, η παράμετρος a είναι απαραίτητη για την αποτίμηση της συνθήκης της εντολής if, η παράμετρος x είναι απαραίτητη για την κλήση της foo2, η μεταβλητή i είναι η μεταβλητή-δείκτης του βρόχου, ενώ η μεταβλητή y προσθέτει τα ενδιάμεσα αποτελέσματα των επαναλήψεων του βρόχου και επιστρέφει το άθροισμα στο καλούν περιβάλλον. Συνεπώς όλες οι μεταβλητές της foo1 πρέπει να διατηρούν την τιμή τους μέσα από την κλήση της συνάρτησης foo2. Από την άλλη μεριά, η συνάρτηση foo2 περιέχει 2 μεταβλητές, τις παραμέτρους n και l. Παρατηρούμε ότι η παράμετρος n δε χρησιμοποιείται μετά την αναδρομική κλήση της foo2, σε αντίθεση με την l, η οποία χρησιμοποιείται για την εύρεση της τελικής διεύθυνσης προσπέλασης του διανύσματος που αυτή παριστάνει. Έτσι, ενώ η πρώτη παράμετρος δεν είναι απαραίτητο να διατηρεί την τιμή της μέσα από την αναδρομική κλήση, η δεύτερη παράμετρος είναι απαραίτητο να τη διατηρεί. Β. Υπάρχουν δύο τρόποι διατήρησης του περιεχομένου μιας μεταβλητής διαμέσου μιας κλήσης σε υποπρόγραμμα: Ο ένας είναι με απ ευθείας αποθήκευση στη στοίβα πριν από την κλήση, και στη συνέχεια με φόρτωση από τη στοίβα μετά την κλήση, της τιμής της μεταβλητής. Ο άλλος είναι μέσω ενός από τους καταχωρητές $s0-s8 που διατηρούν την τιμή τους υ- ποχρεωτικά μέσα από την κλήση 6, με μεταφορά της τιμής της μεταβλητής στον καταχωρητή αυτόν πριν από την κλήση. 5 Υπάρχει μια 1-1 αντιστοίχηση συμβολικών και πραγματικών καταχωρητών. Για παράδειγμα, οι καταχωρητές $4-7 αναφέρονται συμβολικά ως $a0-a3. Η γνώση της ακριβούς αντιστοίχησης δεν είναι απαραίτητη για την κατανόηση της άσκησης, εκτός από την αντιστοίχηση του καταχωρητή $zero στον $0 που έχει προκαθορισμένη τιμή 0, και του $ra στον $31 που χρησιμοποιείται ως υπονοούμενο τελούμενο από την εντολή jal. 6 Η διατήρηση του περιεχομένου των καταχωρητών $s0-s8 μέσα από ένα υποπρόγραμμα δεν είναι χαρακτηριστικό της αρχιτεκτονικής, δηλαδή δε γίνεται αυτόματα. Το περιεχόμενο διατηρείται μέσα από

18 Ο δεύτερος από τους παραπάνω τρόπους επιβαρύνεται με αποθήκευση στη στοίβα του αρχικού περιεχομένου του καταχωρητή και επαναφόρτωση του περιεχομένου αυτού όταν ο καταχωρητής δε θα είναι πλέον απαραίτητος για τη διατήρηση της τιμής της μεταβλητής. Παρά την επιβάρυνση αυτή, ο τρόπος αυτός είναι προτιμότερος, όταν η κλήση στο υποπρόγραμμα γίνεται μέσα σε κάποιο βρόχο, στον οποίο χρησιμοποιείται η εν λόγω μεταβλητή. Τότε, η προσπέλαση στη στοίβα μπορεί να γίνει έξω από το βρόχο αυτόν, μειώνοντας έτσι τις εντολές προσπέλασης μνήμης στο ελάχιστο δυνατό. Ο πρώτος τρόπος διατήρησης του περιεχομένου της μεταβλητής απαιτεί δύο προσπελάσεις μνήμης σε κάθε επανάληψη του βρόχου, γεγονός που μπορεί να οδηγήσει σε μη βέλτιστη επίδοση του κώδικα, επειδή κάθε εντολή προσπέλασης μνήμης ενέχει τον κίνδυνο αποτυχίας στην κρυφή μνήμη με σημαντική αύξηση του συνολικού χρόνου εκτέλεσής της. Λόγω της ύπαρξης του βρόχου στη συνάρτηση foo1, θα εφαρμόσουμε το δεύτερο τρόπο για τη διατήρηση της τιμής των μεταβλητών n, a, x, i και y. Έτσι, ο κώδικας σε συμβολική γλώσσα για τη συνάρτηση αυτή θα χρησιμοποιεί 5 καταχωρητές από τους $s0-s8 και αντίστοιχα 5 θέσεις στη στοίβα για αποθήκευση του αρχικού περιεχομένου αυτών. Αν λοιπόν χρησιμοποιήσουμε τους καταχωρητές $s0, $s1, $s2, $s3 και $s4 για τη διατήρηση της τιμής των μεταβλητών y, i, n, a και x αντίστοιχα, οι εντολές αρχικοποίησης αυτών στην αρχή της foo1 θα είναι: move $s0, $zero move $s1, $zero move $s2, $a0 move $s3, $a1 move $s4, $a2 δεδομένου ότι οι παράμετροι n, a και x της συνάρτησης foo1 περνάνε σε αυτή μέσω των καταχωρητών $a0, $a1 και $a2 αντίστοιχα. Μετά από τις εντολές αυτές, οι καταχωρητές $a0, $a1 και $a2 μπορούν να χρησιμοποιηθούν για προσωρινή αποθήκευση άλλων τιμών, ή για το πέρασμα των παραμέτρων στη συνάρτηση foo2. Οι εντολές προσπέλασης της στοίβας για αποθήκευση του αρχικού περιεχομένου των $s0-s5, μαζί με την εντολή κατάλληλης τροποποίησης της τιμής του $sp, θα συμπεριληφθούν στον τελικό κώδικα. Ο βρόχος που αντιστοιχεί στην εντολή for ξεκινάει με τον έλεγχο της συνθήκης τερματισμού, που υλοποιείται με τις ακόλουθες εντολές συμβολικής γλώσσας: Loop: slt $t0, $s1, $s2 beq $t0, $zero, Break όπου η διεύθυνση της ετικέτας Break θα καθοριστεί αργότερα. Η εντολή if περιλαμβάνει τον έλεγχο της συνθήκης άλματος (a[i] == '\0') που οδηγεί σε δύο κατευθύνσεις, από τις οποίες η πρώτη περιλαμβάνει την κλήση της συνάρτησης foo2. Για την αποτίμηση της συνθήκης άλματος διαβάζουμε από τη μνήμη το στοιχείο a[i] του διανύσματος a. Αυτό μπορεί να γίνει, είτε υπολογίζοντας κάθε φορά εκ νέου τη διεύθυνση του στοιχείου από την αρχική διεύθυνση του διανύσματος και την τιμή του δείκτη i, είτε διατηρώντας σε κάποιον καταχωρητή τη διεύθυνση του στοιχείου και προχωρώντας στο επόμενο στοιχείο με κατάλληλη αυξομείωση της τιμής του καταχωρητή αυτού. Ο δεύτερος τρόπος είναι πιο σύντομος, ενώ επειδή η αρχική διεύθυνση του a δε μας χρειάζεται μετά το βρόχο, μπορούμε να διατηρήσουμε τη διεύθυνση του στοιχείου a[i] στον καταχωρητή $s3, στον ο- ποίο έχουμε αποθηκεύσει την αρχική διεύθυνση του a. Με την ίδια λογική μπορούμε να χρησιμοποιήσουμε τον καταχωρητή $s4 για να διατηρήσουμε τη διεύθυνση του στοιχείου x[i] του διανύσματος x, την οποία χρειαζόμαστε για την κλήση της συνάρτησης foo2. Η κλήση της foo2 γίνεται αφού μεταφέρουμε τις τιμές των παραμέεντολές που παρεμβάλλονται κατάλληλα από το μεταγλωττιστή ή από τον προγραμματιστή συμβολικής γλώσσας, και οι οποίες χρησιμοποιούν τη στοίβα για προσωρινή αποθήκευση.

19 τρων της στους καταχωρητές $a0 και $a1, και αφού σώσουμε στη στοίβα το περιεχόμενο του καταχωρητή $ra, ο οποίος περιέχει τη διεύθυνση επανόδου από τη συνάρτηση foo1. Προκειμένου να αποφύγουμε την εντολή αποθήκευσης του $ra στη στοίβα σε κάθε επανάληψη του βρόχου, την εισάγουμε στην αρχή της foo1. Προφανώς η διεύθυνση επανόδου από την foo1 πρέπει να επαναφορτωθεί στον καταχωρητή $ra πριν την έξοδο από αυτήν. Η εντολή if στο σώμα του βρόχου ολοκληρώνεται με την πρόσθεση στη μεταβλητή y την οποία διατηρούμε στον καταχωρητή $s0 του αποτελέσματος της foo2 στη μια, ή της σταθεράς 1 στην άλλη κατεύθυνση της διακλάδωσης. Το αποτέλεσμα της foo2 λαμβάνεται από τον καταχωρητή $v0, όπου θα πρέπει αυτό να τοποθετείται μέσα από τον κώδικα της συνάρτησης foo2. Με βάση τα παραπάνω, ο κώδικας σε συμβολική γλώσσα που αντιστοιχεί στην εντολή if του αρχικού προγράμματος θα είναι ο εξής: lb $t1, 0($s3) bne $t1, $zero, Else move $a0, $s1 lw $a1, 0($s4) jal foo2 addu $s0, $s0, $v0 j Cont Else: addi $s0, $s0, 1 Ο κώδικας του βρόχου ολοκληρώνεται με την αύξηση του καταχωρητή-δείκτη κατά 1, του καταχωρητή που περιέχει τη διεύθυνση του a[i] κατά 1, και του καταχωρητή που περιέχει τη διεύθυνση του x[i] κατά 4: Cont: addi $s1, $s1, 1 addi $s3, $s3, 1 addi $s4, $s4, 4 j Loop Ο κώδικας της συνάρτησης foo1 ολοκληρώνεται από τη διεύθυνση Break με τη μεταφορά της τιμής της μεταβλητής y στον καταχωρητή $v0, ώστε αυτή να επιστραφεί στο καλούν περιβάλλον, την επαναφόρτωση από τη στοίβα των αποθηκευμένων τιμών των καταχωρητών $s0- s4 και $ra, τη διόρθωση του καταχωρητή $sp στην τιμή που είχε πριν την είσοδο στην foo1, και τέλος την έξοδο από τη foo1. Η συνάρτηση foo2 δεν περιέχει κάποιο βρόχο, κι επομένως η διατήρηση της τιμής της παραμέτρου l μπορεί να γίνει με απ ευθείας αποθήκευση αυτής στη στοίβα αμέσως πριν την αναδρομική κλήση. Η μόνη άλλη τιμή που πρέπει να αποθηκευτεί στη στοίβα είναι η τιμή του $ra που περιέχει τη διεύθυνση επανόδου. Επειδή η χρήση της στοίβας περιορίζεται στην περίπτωση που η αποτίμηση της συνθήκης (n>0) δώσει αποτέλεσμα αληθές, μπορούμε να ξεκινήσουμε τον κώδικα της foo2 με τις εντολές που απαιτούνται για την αποτίμηση της συνθήκης και την κατεύθυνση της διακλάδωσης που αντιστοιχεί σε αποτέλεσμα ψευδές: foo2: bgtz $a0, Then lw $v0, 0($a1) jr $ra όπου υποθέσαμε ότι οι παράμετροι της foo2 λαμβάνονται από τους καταχωρητές $a0 και $a1, ενώ το αποτέλεσμά της επιστρέφεται μέσω του καταχωρητή $v0. Η κατεύθυνση της διακλάδωσης που περιέχει την αναδρομική κλήση της foo2 περιλαμβάνει τις εντολές χειρισμού της στοίβας, τις εντολές υπολογισμού των παραμέτρων της κλήσης, την εντολή της κλήσης, τις εντολές υπολογισμού της τιμής του αποτελέσματος της foo2 που επιστρέφεται στο καλούν περιβάλλον, και την εντολή εξόδου από την foo2. Πιο αναλυτικά, οι εντολές υπολογισμού των παραμέτρων της κλήσης, καθώς και η εντολή κλήσης, θα είναι οι εξής: addi $a0, $a0, -1 addi $a1, $a1, 4