Καταχωρητές GPRs

Η CPU ενός μικροελεγκτή χρησιμοποιεί κάμποσους καταχωρητές για την προσωρινή αποθήκευση δεδομένων τα οποία χρησιμοποιούνται για αριθμητικές καθώς και για λογικές πράξεις.  Σε αυτή την ενότητα θα εξετάσουμε μεταξύ άλλων τους καταχωρητές γενικού σκοπού GPRs του μικροελεγκτή AVR και θα επιδείξουμε τη χρήση των GPRs με τις απλές εντολές LDI και ADD.

Ένας τυπικός μικροελεγκτής AVR  έχει 32 καταχωρητές γενικού σκοπού GPRs που ονομάζονται R0 έως R31. Οι καταχωρητές GPRs ενός μικροελεγκτή AVR έχουν πλάτος 8-bit. Τα 8-bits ενός καταχωρητή γενικού σκοπού δείχνονται στο ακόλουθο διάγραμμα:

Εδώ φαίνεται η περιοχή από το MSB(most – significant – bit) από την ποιο αριστερή θέση στην οποία βρίσκεται το bit D7 έως στο LSD(least – significant – bit) στην ποιο δεξιά θέση στην οποία βρίσκεται το bit D0.

Οι 32 καταχωρητές γενικού σκοπού ενός μικροελεγκτή AVR βρίσκονται στη χαμηλότερη θέση της μνήμης δεδομένων και μπορούν να χρησιμοποιηθούν από όλες τις αριθμητικές και λογικές εντολές.

Η εντολή LDI

Η εντολή LDI αντιγράφει 8-bit κυριολεκτικές τιμές σε ένα καταχωρητή γενικού σκοπού (GPR):

   LDI  Rd, K   ;  φορτώνει στον καταχωρητή Rd την κυριολεκτική αριθμητική τιμή Κ
                ;  d  πρέπει να είναι μεταξύ 16 και 31

Σημείωση: Κ είναι μια 8-bit σταθερή τιμή που μπορεί να είναι δεκαδικός  0 – 255 ή δεκαεξαδικός  0x00 – 0xFF  ενώ ο Rd είναι ένας καταχωρητής GPR από R16 έως R31 (ένας από την μεγαλύτερη ομάδα καταχωρητών)

Παραδείγματα:

  LDI  R21, 0x30  ;  load  R21  with  0x30  (R21 = 0x30)
  LDI  R28, 0x85  ;  load  0x85 into  R28  (R28 = 0x85)

Σημείωση: Δεν μπορούμε να φορτώσουμε τιμές σε καταχωρητές από R0 έως R15 χρησιμοποιώντας την εντολή LDI. Για παράδειγμα η ακόλουθη εντολή δεν είναι έγκυρη:

LDI R5,  0x68  ;   invalid instruction

Παρατηρήστε στην εντολή LDI τη θέση του καταχωρητή αναχώρησης και εκείνου της άφιξης. Όπως μπορείτε να δείτε η εντολή LDI φορτώνει τον δεξιό τελεστή στον αριστερό τελεστή.

Σημείωση: Για να γράψουμε σχόλια στη γλώσσα Assembly χρησιμοποιούμε τον χαρακτήρα του ελληνικού ερωτηματικού «;». Συγκεκριμένα το υπόλοιπο της γραμμής μετά τον χαρακτήρα του ερωτηματικού αγνοείται. Χρησιμοποιείται για να περιγράψουμε την λειτουργία του κώδικα έτσι ώστε αργότερα ο κώδικας να μπορεί να γίνει κατανοητός.

Σημείωση:  Όταν θέλουμε να εισάγουμε ένα δεκαεξαδικό αριθμό τοποθετούμε το σύμβολο του δολαρίου $ ή το 0x μπροστά στην τιμή. Εάν δεν τοποθετήσουμε τίποτα σημαίνει ότι έχουμε δεκαδική τιμή. Για το σύμβολο 0b μπροστά από μια τιμή που είναι σύνολο από 0 και 1 δείχνει δυαδικό αριθμό.

Η εντολή ADD

Η εντολή ADD έχει την ακόλουθη μορφή:

ADD Rd, Rr; πρόσθεσε τα περιεχόμενα του Rr σε εκείνα του Rd και φόρτωσε το αποτέλεσμα πίσω στον Rd

Παράδειγμα:

LDI  R19,  0x65     ;      load  0x65   into    R19
LDI  R20,  0x44     ;      load  0x44   into    R20
ADD R19,  R20     ;       add value  R20 to  R19  (R19 = R19 + R20)

Η εντολή  MOV

Η εντολή MOV χρησιμοποιείται για να αντιγράψει δεδομένα μεταξύ καταχωρητών γενικού σκοπού GPR από R0 έως R31

MOV  Rd,  Rr  ;  Rd = Rr  (αντέγραψε τον Rr  στον  Rd)
              ;  Rd και Rr  μπορεί να είναι οποιοδήποτε από τους GPRs

Παράδειγμα:

Η επόμενη εντολή αντιγράφει τα περιεχόμενα του R22 στον R12:

MOV  R12,  R22   ;   R12 = R22
Αν ο R22 περιέχει την τιμή 70 μετά την εκτέλεση της παραπάνω εντολής και οι δυο R22 και R12 θα περιέχουν την ίδια τιμή 70.

Παράδειγμα

Το επόμενο κομμάτι κώδικα προσθέτει την τιμή 0x25 στα περιεχόμενα της θέσης 0x230 της μνήμης δεδομένων και αποθηκεύει το αποτέλεσμα στη θέση 0x235:

LDI  R21, 0x25  ;  load R21 with  0x25
LDS R22, 0x230  ;  load R21 with the contents of location on 0x230
ADD R22, R21  ;  R22=R22+R21
STS  0x235, R22   ;  store  R21  to  location  0x235

Η εντολή SUB

Η εντολή SUB έχει την ακόλουθη σύνταξη:

SUB  Rd,  Rr    ;     Rd = Rd – Rr

Η εντολή SUB προκαλεί τη CPU να αφαιρέσει την τιμή του καταχωρητή Rr  από τον Rd και να βάλει το αποτέλεσμα πίσω στον καταχωρητή Rd.

Παράδειγμα

Στο ακόλουθο κομμάτι κώδικα αφαιρούμε την τιμή 0x30 από την τιμή 0x45:

LDI  R18,  0x30  ;  R18 = 0x30
LDI  R19, 0x45   ;  R19 = 0x45
SUB  R19, R18    ;  R19 = R19 – R18

Παράδειγμα

Το επόμενο κομμάτι κώδικα, αφαιρεί την τιμή 0x08 από τα περιεχόμενα της θέσης 0x350 και αποθηκεύει το αποτέλεσμα στη θέση 0x380:

LDS  R10, 0x350  ;   R10 = contents of location 0x350
LDI  R20, 0x08   ;  R20 = 0x08
SUB  R10,  R20   ;  R10 = R10 – R16
STS  0x380, R10  ;  store the contents of  R10 to location 0x380

Παράδειγμα

Το επόμενο κομμάτι κώδικα μειώνει τα περιεχόμενα του R12 κατά 1:

LDI  R18, 0x01
SUB  R12,  R18
Εντολές που χρησιμοποιούν δυο GPRs

Η εντολή INC

Η εντολή INC έχει την ακόλουθη σύνταξη:

INC  Rd  ;  αύξησε τα περιεχόμενα του Rd κατά 1

Παράδειγμα

Η ακόλουθη εντολή προσθέτει 1 στα περιεχόμενα του R5:

 INC  R5  ;  R5 = R5+1

Παράδειγμα

Το ακόλουθο κομμάτι κώδικα αυξάνει τα περιεχόμενα της θέσης 0x450 της μνήμης δεδομένων κατά 1:

    LDS  R18, 0x450  ;  R18 = contents of location 0x450
    INC  R18   ;    R18 = R18 + 1
    STS 0x450, R18  ;  store  R18 to location 0x450

Η εντολή  DEC

Η εντολή  DEC  έχει την ακόλουθη σύνταξη:

DEC  Rd  ;  Rd = Rd – 1

Η εντολή DEC μειώνει  (αφαιρεί 1 από) τα περιεχόμενα του καταχωρητή Rd και βάζει το αποτέλεσμα πίσω στον καταχωρητή Rd.

Παράδειγμα

Η επόμενη εντολή αφαιρεί 1 από τα περιεχόμενα του R14:

DEC R14  ;  R10 = R10 – 1

Η εντολή  COM

Η εντολή  COM  Rd  παρέχει το συμπλήρωμα ως προς ένα του καταχωρητή Rd και μετά βάζει το αποτέλεσμα πίσω στον Rd. Το συμπλήρωμα ως προς ένα μιας δυαδικής τιμής 8-bit δίνεται αντικαθιστώντας τα 0 με 1 και τα 1 με 0.

Παράδειγμα

Στο επόμενο κομμάτι κώδικα βάζουμε την τιμή 0x55 στον R20 και την στέλνουμε στη θύρα PORTD. Μετά παίρνουμε το συμπλήρωμα ως προς 1 του καταχωρητή R20 που γίνεται 0xAA στο δεκαεξαδικό. Δηλαδή παίρνουμε το συμπλήρωμα της τιμής 01010101 (0x55) που γίνεται 10101010 (0xAA), και το στέλνουμε στη θύρα D:

LDI  R20,  0x55  ;  R20 = 0x55
OUT  PORTD, R20  ;  copy  R20  to port D  (PORTD = 0x55)
COM  R20         ;  complement  R20
OUT  PORTD, R20  ;  copy  R20  to port D  (PORTD = 0xAA)
Εντολές που χρησιμοποιούν έναν GPR