ΗΥ-225: Οργάνωση Υπολογιστών
Άνοιξη 2007
Τμ. Επ. Υπολογιστών
© Πανεπιστήμιο Κρήτης

Σειρά Ασκήσεων 2:
Βρόχοι και Επικοινωνία Κονσόλας στον SPIM

Προθεσμία έως Δευτέρα 26 Μαρτίου 2007, ώρα 23:59 (βδομάδα 3.1) (από βδ.2.1)
[Up: Table of Contents]
[Prev - 1. SPIM Introduction]
[printer version - PDF]
[3. Memory Accesses - Next]

2.1   Εντολές Διακλάδωσης υπό Συνθήκη στον MIPS

Όπως λέγαμε και στην §
1.3, γιά να εκτελεστεί ένα πρόγραμμα, οι εντολές του γράφονται στην κεντρική μνήμη η μία "κάτω" από την άλλη, δηλαδή σε συνεχόμενες θέσεις (διευθύνσεις) μνήμης. Μετά την ανάγνωση και εκτέλεση μιάς εντολής, ο επεξεργαστής αυξάνει τον PC κατά το μέγεθος της εντολής που εκτελέστηκε, οπότε αυτός (ο PC) δείχνει στην επόμενη (την "από κάτω") εντολή. Η σειριακή αυτή εκτέλεση εντολών διακόπτεται όταν εκτελείται μιά εντολή μεταφοράς ελέγχου (CTI - control transfer instruction). Είδαμε ήδη μία τέτοια, την εντολή άλματος j label ("jump" to label), που κάνει ώστε η επόμενη εντολή που θα εκτελεστεί να είναι η εντολή στη διεύθυνση μνήμης label, αντί να είναι η "από κάτω" εντολή. Με άλλα λόγια, η εντολή j label φορτώνει τη διεύθυνση label στον καταχωρητή PC. Χρησιμοποιώντας αυτή την εντολή άλματος στην άσκηση 1 φτιάξαμε έναν "άπειρο βρόχο", δηλαδή κάναμε τον υπό προσομοίωση υπολογιστή να εκτελεί συνεχώς το ίδιο "μπλόκ" εντολών.

Γιά να φτιάξουμε ένα κανονικό (όχι άπειρο) βρόχο χρειαζόμαστε μιάν εντολή διακλάδωσης υπό συνθήκη (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

Τρόπος Παράδοσης:
Θα παραδώσετε ηλεκτρονικά ένα στιγμιότυπο της οθόνης καθώς τρέχετε το πρόγραμμα "xspim" και αυτό βρίσκεται σ' ένα "ενδιαφέρον" ενδιάμεσο breakpoint. Το στιγμιότυπο θα το πάρετε και θα το παραδώσετε κατ' αναλογία πρός την παράδοση της άσκησης 1:


[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.