ΗΥ-225: Οργάνωση Υπολογιστών
Άνοιξη 2007 |
Τμ. Επ. Υπολογιστών © Πανεπιστήμιο Κρήτης |
[Up: Table of Contents] [Prev - 1. SPIM Introduction] |
[printer version - PDF] [3. Memory Accesses - Next] |
Γιά να φτιάξουμε ένα κανονικό (όχι άπειρο) βρόχο
χρειαζόμαστε μιάν εντολή
διακλάδωσης υπό συνθήκη (conditional branch),
δηλαδή μιάν εντολή που μερικές φορές προκαλεί διακλάδωση
και μερικές φορές όχι,
ανάλογα με το αν ισχύει ή δεν ισχύει κάποια κατάλληλη συνθήκη.
Η βασική τέτοια εντολή είναι η
beq (branch if equal):
Η εντολή "beq $16, $17, label"
διαβάζει τους καταχωρητές 16 και 17, και τους συγκρίνει.
Εάν τους βρεί ίσους (equal) διακλαδίζεται στη θέση label,
δηλαδή κάνει τον επεξεργαστή να διαβάσει και εκτελέσει την εντολή
από εκείνη τη διεύθυνση σαν επόμενη εντολή.
Αλλοιώς, δεν κάνει τίποτα,
οπότε επόμενη εντολή θα διαβαστεί και εκτελεστεί η "από κάτω" εντολή.
Η εντολή bne (branch if not equal) κάνει τα ανάποδα,
δηλαδή διακλαδίζεται εάν βρεί τους καταχωρητές άνισους (not equal),
αλλοιώς συνεχίζει "από κάτω".
2.2 Κώδικας Βρόχου και Εισόδου/Εξόδου Κονσόλας
Γιά να επικοινωνούν τα προγράμματα που τρέχουμε στον SPIM
με τον έξω κόσμο, ο SPIM προσομοιώνει
μερικές υποτυπώδεις υπηρεσίες λειτουργικού συστήματος
γιά είσοδο/έξοδο (I/O) στην "κονσόλα" (ένα απλό τερματικό ASCII).
Δεν είναι ανάγκη προς στιγμήν να καταλάβετε όλες τις λεπτομέρειες
του πώς γίνεται η κλήση αυτών των λειτουργιών (system call)
--αρκεί να μιμηθείτε το παρακάτω παράδειγμα
και να καταλάβετε τις εξηγήσεις που δίνονται κάτω από αυτό.
Μελετήστε και αντιγράψτε
σε ένα αρχείο (π.χ. "ask2.s")
τον παρακάτω κώδικα
--ή διάφορες παραλλαγές του που προτιμάτε--
και τρέξτε τον στον SPIM.
# compute s = 1+2+3+...+(n-1), for n>=2
# register $16: n
# register $17: s
# register $18: i
.data # init. data memory with the strings needed:
str_n: .asciiz "n = "
str_s: .asciiz " s = "
str_nl: .asciiz "\n"
.text # program memory:
.globl main # label "main" must be global;
# default trap.handler calls main.
.globl loop # global symbols can be specified
# symbolically as breakpoints.
main: # (1) PRINT A PROMPT:
addi $2, $0, 4 # system call code for print_string
la $4, str_n # pseudo-instruction: address of string
syscall # print the string from str_n
# (2) READ n (MUST be n>=2 --not checked!):
addi $2, $0, 5 # system call code for read_int
syscall # read a line containing an integer
add $16, $2, $0 # copy returned int from $2 to n
# (3) INITIALIZE s and i:
add $17, $0, $0 # s=0;
addi $18, $0, 1 # i=1;
loop: # (4) LOOP starts here
add $17, $17, $18 # s=s+i;
addi $18, $18, 1 # i=i+1;
bne $18, $16, loop # repeat while (i!=n)
# LOOP ENDS HERE
# (5) PRINT THE ANSWER:
addi $2, $0, 4 # system call code for print_string
la $4, str_s # pseudo-instruction: address of string
syscall # print the string from str_s
addi $2, $0, 1 # system call code for print_int
add $4, $17, $0 # copy argument s to $4
syscall # print the integer in $4 (s)
addi $2, $0, 4 # system call code for print_string
la $4, str_nl # pseudo-instruction: address of string
syscall # print a new-line
# (6) START ALL OVER AGAIN (infinite loop)
j main # unconditionally jump back to main
Ο κώδικας αυτός υπολογίζει το άθροισμα s=1+2+3+...+(n-1),
γιά n μεγαλύτερο ή ίσο του 2
--προσοχή: αν δοθεί n μικρότερο του 2,
ο κώδικας θα μπεί σε (σχεδόν) άπειρο βρόγχο!
Η "καρδιά" του κωδικά είναι τα κομάτια (3) --αρχικοποιήσεις--
και (4) --βρόγχος υπολογισμού.
Προσέξτε τις παρακάτω εξηγήσεις:
Άσκηση 2.3: Τρέξιμο στον SPIM
[Up: Table of Contents] [Prev - 1. SPIM Introduction] |
[printer version - PDF] [3. Memory Accesses - Next] |
Up to the Home Page of CS-225
|
© copyright
University of Crete, Greece.
Last updated: 19 Mar. 2007, by M. Katevenis. |