ΗΥ-225: Οργάνωση Υπολογιστών
Άνοιξη 2010 |
Τμήμα Επιστήμης Υπολογιστών © Πανεπιστήμιο Κρήτης |
[Up - Table of Contents] [Prev - 4. Instruction Formats] |
[printer version - PDF] [6. Procedure Call - Next] |
Οι εντολές μεταφοράς ελέγχου (CTI, control transfer instructions) καθορίζουν να εκτελεστεί σαν επόμενη εντολή –πάντοτε ή υπό ορισμένες συνθήκες μόνο– μια έντολη άλλη από την "επόμενη από κάτω" τους εντολή. Όταν η μεταφορά ελέγχου γίνεται υπό συνθήκη, οι εντολές συνήθως ονομάζονται διακλαδώσεις (branch). Όταν η μεταφορά γίνεται πάντοτε, οι εντολές συνήθως λέγονται άλματα (jump). Επίσης υπάρχουν καλέσματα διαδικασιών, λειτουργικού συστήματος, και επιστροφές από αυτά. Στον MIPS, η συνθήκη διακλάδωσης μπορεί να έχει περιορισμένες μόνο μορφές, γιά λόγους ταχύτητας. Οι μόνες συνθήκες διακλαδώσεων που υπάρχουν αφορούν συγκρίσεις ενός καταχωρητή με το μηδέν (δεν θα ασχοληθούμε με αυτές στο "δικό μας" υποσύνολο του MIPS), και συγκρίσεις δύο καταχωρητών μόνο γιά ισότητα ή ανισότητα και όχι γιά άλλων μορφών σχέσεις (μικρότερος, μεγαλύτερος, κλπ). Οι εντολές αυτές είναι:
Οι υπόλοιπες μορφές συγκρίσεων, που δεν γίνονται μέσα στις εντολές διακλάδωσης, υλοποιούνται με ειδικές, ξεχωριστές, αριθμητικές εντολές σύγκρισης. Πρόκειται γιά εντολές ανάλογες προς την πρόσθεση ή την αφαίρεση, μόνο που το αποτέλεσμά τους είναι τύπου Boolean αντί τύπου ακέραιος. Τέτοια αποτελέσματα τύπου Boolean έχουν δύο μόνο δυνατές τιμές: 0 γιά ψευδές, και 1 γιά αληθές. Τα αποτελέσματα αυτά γράφονται στους γνωστούς μας, κανονικούς (32μπιτους) καταχωρητές, σαν οι ακέραιοι 0 ή 1, δηλαδή στο LS bit του καταχωρητή, με όλα τα υπόλοιπα bits του καταχωρητή μηδενικά. Οι εντολές σύγκρισης που εμείς θα έχουμε στο δικό μας υποσύνολο του MIPS είναι οι:
Εκτός από τις εντολές διακλάδωσης υπό συνθήκη, το υποσύνολο εντολών του MIPS που χρησιμοποιούμε στο μάθημα περιλαμβάνει και τις παρακάτω άλλες εντολές μεταφοράς ελέγχου:
Έστω ότι θέλουμε να υλοποιήσουμε μία απλή δομή if-then-else της γλώσσας προγραμματισμού C, όπως στον παρακάτω κώδικα, ο οποίος αναθέτει σε μία μεταβλητή το μέγιστο μεταξύ δύο στοιχείων.
if (i < j) a = j; else /* i >= j */ a = i;Για την υλοποίηση αυτή πρέπει να αξιοποιήσουμε τις εντολές διακλάδωσης σε συνδυασμό με τις εντολές σύγκρισης. Αν υποθέσουμε ότι οι μεταβλητές i, j, a βρίσκονται στους καταχωρητές $8, $9, $16 (δηλαδή τους $t0, $t1, $s0 αν χρησιμοποιούμε συμβολικά ονόματα καταχωρητών), τότε η σύγκριση if (i < j) μπορεί να μεταφραστεί στην εντολή:
slt $10, $8,$9 #if (i < j), $10 = 1 bne $10, $0, thenpath #jump to then path add $16, $8, $0 # this is the else path, a = i; j exit # we don't want to execute the then path! then: add $16, $9, $0 #this is the then path, a = j; exit:
Παρατηρήστε ότι σε αντίθεση με τη γλώσσα προγραμματισμoύ C, στην assembly αν η συνθήκη είναι αληθής εκτελείται το άλμα στο "μονοπάτι" then και όχι η εντολή που βρίσκεται κάτω από τον έλεγχο της συνθήκης. Αντίθετα η συγκεκριμένη εντολή υλοποιεί το "μονοπάτι" else. Ωστόσο, δεδομένου ότι ο κώδικας πρέπει να εκτελέσει είτε το μονοπάτι then, είτε το μονοπάτι else αλλά όχι και τα δύο μονοπάτια, χρησιμοποιούμε μία εντολή j για να αποφύγουμε το μονοπάτι then αν έχουμε εκτελέσει το μονοπάτι else. Ας υποθέσουμε ότι θέλουμε να "διορθώσουμε" αυτή την ασυμμετρία μεταξύ C και assembly έτσι ώστε στον κώδικά assembly να εμφανίζεται πρώτα το then μονοπάτι και μετά το else μονοπάτι. Δώστε τον ισοδύναμο κώδικα σε assembly μετά από αυτή την αλλαγή. Εάν σας εξυπηρετεί, δοκιμάστε τον κώδικα στον SPIM για να επαληθεύσετε ότι η λύση σας είναι σωστή.
Στις γλώσσες προγραμματισμού υψηλού επιπέδου χρησιμοποιούνται συχνά δομές switch...case οι οποίες επιλέγουν μεταξύ τυπικά πολλών εναλλακτικών μονοπατιών κώδικα που ακολουθούνται με βάση την τιμή μίας μεταβλητής ελέγχου, όπως για παράδειγμα ο κώδικας:
switch (n) { case 0: a = b + c; break; case 1: a = d + e; break; case 2: a = b - c; break; case 3: a = d - e; break; default: break; }Αν και οι δομές αυτές θα μπορούσαν να υλοποιηθούν με ακολουθίες από δομές if-then-else, αυτό θα περιέπλεκε αρκετά τον κώδικα και θα αύξανε σημαντικά το μέγεθός του. Για να παράγουμε πιο σύντομο και αποδοτικό κώδικα σε αυτές τις περιπτώσεις χρησιμοποιούμε πίνακες διευθύνσεων αλμάτων (jump address tables) στη μνήμη. Συγκεκριμένα, για κάθε πιθανό μονοπάτι του case αναθέτουμε μία ετικέτα (που δείχνει στην αρχή του κώδικα του μονοπατιού), της οποίας τη διεύθυνση αποθηκεύουμε στη μνήμη, σε έναν πίνακα. Ο πίνακας αυτός περιέχει τόσες διευθύνσεις όσα τα εναλλακτικά μονοπάτια της δομής switch...case και αρχικοποιείται με τις ετικέτες, κάθε μία από τις οποίες ορίζει ένα μονοπάτι. Ο κώδικας που υλοποιεί το switch...case ελέγχει την τιμή της μεταβλητής ελέγχου, και τη χρησιμοποιεί σαν δείκτη στον πίνακα με τις ετικέτες. Για παράδειγμα, αν χρησιμοποιείται μία μεταβλητή ελέγχου n όπως παραπάνω, ο κώδικας πολλαπλασιάζει το n με 4 για να βρει την αντίστοιχη ετικέτα, φορτώνει τη διεύθυνση της ετικέτας σε έναν καταχωρητή (με εντολές la, lw) και κατόπιν χρησιμοποιεί την εντολή jr με την τιμή του καταχωρητή για να κάνει το άλμα στο σωστό μονοπάτι. Η δομή switch...case είναι μία απο τις σημαντικές περιπτώσεις χρήσης της εντολής jr Στο μάθημα θα υλοποιήσουμε ένα παράδειγμα δομής switch...case
Είπαμε ότι, γιά λόγους ταχύτητας, οι μόνες συνθήκες διακλάδωσης του MIPS που αφορούν δύο αυθαίρετους αριθμούς (όχι έναν αριθμό και το μηδέν) είναι συγκρίσεις ισότητας/ανισότητας και όχι συγκρίσεις μεγαλύτερος/μικρότερος. Ομως, επίσης, οι εντολές αυτές (beq, bne) υπάρχουν μόνο στη μορφή που δέχεται δύο καταχωρητές σαν τελεστέους, και δεν μπορούν να συγκρίνουν καταχωρητή με σταθερή ποσότητα (immediate). Ο λόγος δεν μπορεί να έχει να κάνει με ταχύτητα, αφού η σύγκριση ισότητας/ανισότητας καταχωρητή-σταθεράς είναι τουλάχιστο το ίδιο γρήγορη με την αντίστοιχη σύγκριση δύο καταχωρητών. Γιατί λοιπόν πιστεύετε ότι δεν υπάρχουν τέτοιες εντολές "beqi" και "bnei" στον MIPS; Δώστε την απάντησή σας και εξηγήστε.
Έστω ότι η μεταβλητή i βρίσκεται στον καταχωρητή $16, η μεταβλητή j στον καταχωρητή $17, και ότι CONST σημαίνει μια αυθαίρετη προσημασμένη σταθερή ποσότητα μέχρι και 16 bits. Συνθέστε τις παρακάτω περιπτώσεις κώδικα χρησιμοποιώντας αποκλειστικά και μόνο εντολές μεταξύ των:
Μεταφράστε τον παρακάτω κώδικα C που υλοποιεί ένα βρόχο while σε Assembly. Θεωρήστε ότι ο καταχωρητής $16 περιέχει την αρχική διεύθυνση του πίνακα a[] στη μνήμη και ότι ο καταχωρητής $9 περιέχει τον δείκτη του βρόχου i. Ο κώδικάς σας πρέπει: i) να υπολογίζει σωστά τις θέσεις μνήμης των στοιχείων του πίνακα a[] χρησιμοποιώντας μόνο εντολές add, addi; ii) να εκτελεί μόνο ένα branch ή jump σε κάθε ανακύκλωση (Κατά την είσοδο ή την έξοδο από το βρόχο επιτρέπεται να εκτελούνται δύο εντολές μεταφοράς ελέγχου –αυτό που μας ενδιαφέρει είναι να γλυτώνουμε τη μια από αυτές κατά τις υπόλοιπες επαναλήψεις του βρόχου, που αποτελούν και την πλειοψηφία των φορών που αυτός εκτελείται).
while (a[i] >= 4) { i = i+1; }Έστω ότι ο βρόχος εκτελείται 225 φορές. Πόσες εντολές συνολικά εκτελούνται με τον κώδικά σας;
Τρόπος Παράδοσης:
Για να παραδώσετε την άσκηση χρησιμοποιήστε την ακόλουθη διαδικασία.
Συνδεθείτε σε ένα μηχάνημα Linux του τμήματος με το login και
password που χρησιμοποιείτε στο Τμήμα. Η λίστα μηχανημάτων Linux
του Τμήματος είναι διαθέσιμη
εδώ. Ετοιμάστε ένα directory με το αρχείο που σας ζητάει η
άσκηση (ask5.txt).
Ας υποθέσουμε ότι το όνομα του directory είναι <somepath>/mydir. Μετακινηθείτε
στο directory <somepath> και εκτελέστε την εντολή:
/usr/local/bin/submit exercise5@hy225 mydir
Η διαδικασία submit θα σας ζητήσει να επιβεβαιώσετε την αποστολή των αρχείων.Περισσότερες πληροφορίες και αναλυτικές οδηγίες για τη νέα διαδικασία submit είναι διαθέσιμες εκτελώντας:
man submit
σε κάποιο από τα μηχανήματα Linux του Τμήματος. Σημειώστε ότι η απομακρυσμένη πρόσβαση στα μηχανήματα του Τμήματος γίνεται από 1.2.2010 με νέο ασφαλή τρόπο μέσω gateways και με χρήση tunnel.
[Up - Table of Contents] [Prev - 4. Instruction Formats] |
[printer version - PDF] [6. Procedure Call - Next] |
Up to the Home Page of CS-225
|
© copyright University of Crete, Greece. Last updated: , by D. Nikolopoulos. |