19. H macro directive

Υπάρχουν εφαρμογές στον προγραμματισμό σε γλώσσα Assembly στις οποίες μια ομάδα εντολών εκτελεί μια εργασία η οποία επαναλαμβάνεται στο ίδιο πρόγραμμα. Είναι βαρετό να γράφουμε ξανά και ξανά αυτήν την ομάδα εντολών όποτε χρειάζεται. Επομένως για να μειώσουμε το χρόνο εγγραφής του κώδικα και να μειώσουμε την πιθανότητα λαθών χρησιμοποιούμε την έννοια των macros. Τα macros επιτρέπουν στον προγραμματιστή να γράψει το κομμάτι του επαναλβανόμενου κώδικα μια φορά και να το επικαλείται όποτε το χρειάζεται.

Ορισμός του Macro

Κάθε ορισμός macro πρέπει να έχει τρία τμήματα:

 .MACRO   name
 ...
 .ENDMACRO

H .MACRO directive ορίζει την αρχή του ορισμού του macro και η .ENDMACRO directive ορίζει το τέλος της. Το τμήμα του κώδικα μεταξύ των directive .MACRO και .ENDMACRO ονομάζεται σώμα του macro. Το όνομα θα πρέπει να είναι μοναδικό και θα πρέπει να ακολουθεί τις συμβάσεις ονοματοδοσίας της γλώσσας Assembly. Ένα macro θα πρέπει να έχει το πολύ 10 παραμέτρους σαν @0 έως @9 στο σώμα του macro. Μετά που θα γράψουμε τον ορισμό του macro μπορούμε να το επικαλούμαστε μέσα στο πρόγραμμα με το όνομα του ακολουθούμενο από τις κατάλληλες τιμές που θα αντικαταστήσουν τις παραμέτρους.

Για παράδειγμα επικαλούμαστε την εργασία στην οποία φορτώνουμε σταθερές τιμές στους Ι/Ο καταχωρητές της μνήμης δεδομένων. Επειδή είναι μια συνηθισμένη εργασία και για το λόγο ότι δεν υπάρχει συγκεκριμένη εντολή για αυτή την ομάδα εντολών χρησιμοποιούμε ένα macro για να εκτελέσουμε αυτή την εργασία:

  .MACRO  LOADIO
         LDI  R16, @1
         OUT  @0, R16
  .ENDMACRO

Το προηγούμενο κομμάτι κώδικα είναι ένας ορισμός macro. Οι παράμετροι @0 και @1 αναφέρονται στο σώμα της macro.

Ακολουθούν τρία παραδείγματα

LOADIO  PORTC, 0x1A  ;  στείλε την τιμή 0x1A στην PORTC
LOADIO SPL, 0x5C     ;  στείλε την τιμή 0x5C στον SPL
.EQU VAL1 = 0xBB
LOADIO DDRC, VAL1

Παράδειγμα: Μελετήστε το ακόλουθο πρόγραμμα, το οποίο εναλλάσσει τα περιεχόμενα της PORTB, για να δείτε πως χρησιμοποιούνται τα macro:

; Program: toggling PortB using macros
;--------
.MACRO LOADIO
          LDI   R16, @1
          OUT   @0, R16
.ENDMACRO
; -------time delay macro
.MACRO  DELAY
       LDI @0, @1
BACK:
      NOP
      NOP
      NOP
      NOP
      DEC  @0
      BRNE  BACK
.ENDMACRO
; -------program starts
.ORG 0
    LOADIO  DDRB, 0xFF   ; κάνε την PORTB έξοδο
L1: LOADIO  PORTB, 0x55  ; PORTB = 0x55
    DELAY   R18, 0x70    ; delay
    LOADIO  PORTB, 0xAA  ; PORTB = 0xAA
    DELAY   R18, 0x70    ; delay
    RJMP    L1