czwartek, 13 sierpień 2020
 
Strona główna Mikrokontrolery 8051 Makroinstrukcje

Makroinstrukcje w DSM51

  1. Zasady tworzenia makroinstrukcji
  2. Przełączanie między bankami rejestrów
  3. Operacje na stosie
  4. Operacje rotacji
  5. Wywołanie procedury z parametrem

  1. Zasady tworzenia makroinstrukcji

    Makroinstrukcja (makro) to zestaw instrukcji asemblera. Po zdefiniowaniu makroinstrukcja może być włączona w kod źródłowy programu poprzez jej wywołanie. W treści makr mogą występować bez ograniczeń wywołania innych makr, za wyjątkiem samego siebie.

    Składnia:

    Dyrektywa definicji makra
    NAZWA   MACRO   parametry   ;początek definicji makra.
             :
            treść makroinstrukcji
             :
            ENDM                ;(lub MACEND) koniec definicji.
    

    Parametry to oddzielone przecinkami symbole (parametry formalne makra), które mogą być wykorzystywane w treści makra. Przy wywołaniu podawane są parametry aktualne makra, które zastępują wszystkie parametry formalne. Makro jest wywoływane poprzez umieszczenie jego nazwy w polu rozkazu danej linii programu. np:

    [etykieta:] NAZWA  par1,par2,... 

    Asembler (w tej wersji!) nie umożliwia tworzenia etykiet lokalnych w makrach. Jeśli występuje taka potrzeba to można podawać etykietę (lub jej fragment) jako jeden z parametrów makra. Jest to możliwe, gdyż zastępowanie parametrów formalnych parametrami aktualnymi odbywa się na drodze podmieniania tekstów przed asemblacją linii programu. Teksty te są podmieniane niezależnie od tego, czy występują w etykiecie, nazwie mnemonika, czy w treści operandu.

    do góry
  2. Przełączanie między bankami rejestrów

    O aktualnie używanym banku rejestrów decydują bity RS0 i RS1 znajdujące się w rejestrze PSW (RS1=PSW.4, RS0=PSW.3). Bity te tworzą słowo oznaczające numer banku. Podstawowe makra są następujące:

    Banki rejestrów 0..3
    BANK0   MACRO
            CLR     RS0
            CLR     RS1
            ENDM
    ;---------------------------------------
    BANK1   MACRO
            SETB    RS0
            CLR     RS1
            ENDM
    ;---------------------------------------
    BANK2   MACRO
            CLR     RS0
            SETB    RS1
            ENDM
    ;---------------------------------------
    BANK3   MACRO
            SETB    RS0
            SETB    RS1
            ENDM
    

    Jeżeli używamy tylko banków 0 i 1 to można te makra uprościć:

    Banki rejestrów 0 i 1
    BANK0   MACRO
            CLR     RS0
            ENDM
    ;---------------------------------------
    BANK1   MACRO
            SETB    RS0
            ENDM
    

    Jeżeli pozostałe bity PSW są nieistotne można również użyć instrukcji ośmiobitowej, stosując makro z parametrem:

    Banki rejestrów (z parametrem)
    BANK    MACRO   %NUMER
            MOV     PSW,#%NUMER*8
            ENDM
    

    Wywołanie takiego makra może mieć np. taką postać:

            BANK    2
    do góry
  3. Operacje na stosie

    Operacjami wykorzystującymi stos są PUSH, POP, xCALL, RET i RETI. Instrukcje PUSH i POP występują wyłącznie z adresowaniem bezpośrednim, co często jest dość uciążliwe. Na przykład nie są możliwe następujące instrukcje:

         PUSH    R3    
         POP     @R1   
    

    Poniższe makra załatwiają sprawę:

    PUSH i POP dla rejestrów
    PUSHR   MACRO   %REJESTR
            XCH     A,%REJESTR
            PUSH    ACC
            XCH     A,%REJESTR
            ENDM
    ;---------------------------------------
    POPR    MACRO   %REJESTR
            XCH     A,%REJESTR
            POP     ACC
            XCH     A,%REJESTR
            ENDM
    

    Parametrami wywołania mogą być: R0, R1, R2 ... R7, @R0 i @R1.
    Jeżeli zawartość akumulatora jest nieistotna, to można te makra uprościć:

    PUSH i POP dla rejestrów
    PUSHR   MACRO   %REJESTR
            MOV     A,%REJESTR
            PUSH    ACC
            ENDM
    ;---------------------------------------
    POPR    MACRO   %REJESTR
            POP     ACC
            MOV     %REJESTR,A
            ENDM
    

    Wywołanie takiego makra może mieć np. taką postać:

            PUSHR   R3    
            POPR    @R1   
    

    Czasem może wystąpić konieczność skopiowania wierzchołka stosu do rejestru pamięci. Zrobi to makro:

    Kopia wierzchołka stosu
    KOPIAS  MACRO   %REJESTR
            POP     %REJESTR
            PUSH    %REJESTR
            ENDM
    
    do góry
  4. Operacje rotacji

    Instrukcje rotacji (RR RL RRC RLC) dotyczą tylko akumulatora (niestety). Często jednak zachodzi potrzeba rotacji komórki pamięci lub rejestru. Poniższe makra rozwiążą problem:

    RL
    RLREJ   MACRO   %REJESTR
            XCH     A,%REJESTR
            RL      A
            XCH     A,%REJESTR
            ENDM
    ;---------------------------------------
    ; dla RR, RLC i RRC analogicznie
    

    Można również stworzyć uniwersalne makro:

    rotacje
    ROT     MACRO   %ROZKAZ,%REJESTR
            XCH     A,%REJESTR
            %ROZKAZ A
            XCH     A,%REJESTR
            ENDM
    ;---------------------------------------
    ; przykładowe wywołania:
            ROT     RLC,@R1
            ROT     RR,R5
            ROT     RL,45H
    
    do góry
  5. Wywołanie procedury z parametrem

    Często zdarza się, że wykorzystujemy procedury, do których przekazywany jest jeden parametr. Przykłady:

    • procedura opóźnienia, czas w ms w akumulatorze, (CZASA)
    • procedura opóźnienia, czas w ms w DPTR, (CZASD)
    • procedura wypisania znaku na wyświetlaczu, kod znaku w akumulatorze, (PISZZNAK)
    • procedura wypisania tekstu na wyświetlaczu, adres początku tekstu w DPTR, tekst zakończony 0 (PISZTXT)
    • itp

    W takich przyadkach zastosowanie makroinstrukcji znacznie skraca zapis programu, zwłaszcza, gdy procedury te wywoływane są często.
    Przykłady:

    procedura CZASA z parametrem 8-bitowym
    CZAS1   MACRO   %ILE
            MOV     A,%ILE
            ACALL   CZASA
            ENDM
    ;---------------------------------------
    ; przykładowe wywołania:
            CZAS1   #100      ;100 ms
            CZAS1   27        ;czas zapisany w pamięci pod adresem 27
            CZAS1   OPOZN     ;czas zapisany w pamięci w komórce o nazwie OPOZN
            CZAS1   R2        ;czas zapisany w R2
    

    procedura CZASD z parametrem 16-bitowym
    CZAS2   MACRO   %ILE
            MOV     DPTR,#%ILE
            ACALL   CZASD
            ENDM
    ;---------------------------------------
    ; przykładowe wywołanie:
            CZAS2   2500      ;2500 ms = 2,5 s
    

    procedura PISZZNAK
    PISZZ   MACRO   %KOD
            MOV     A,#%KOD
            ACALL   PISZZNAK
            ENDM
    ;---------------------------------------
    ; przykładowe wywołania:
            PISZZ   'A'       ;znak A
            PISZZ   '+'       ;znak +
            PISZZ   167       ;znak o kodzie 167
            PISZZ   0C7H      ;znak o kodzie szesnastkowym C7
            PISZZ   LPOL      ;znak o kodzie będącym stałą LPOL
    

    procedura PISZTXT
    PISZT   MACRO   %TEKST
            MOV     DPTR,#%TEKST
            ACALL   PISZTXT
            ENDM
    ;---------------------------------------
    ; przykładowe wywołania:
            PISZT   AUTOR
            PISZT   ALARM
            PISZT   KASUJ5
    ; stałe tekstowe
    AUTOR   DB      '(c) Piotr Kotarski',0
    ALARM   DB      'Uwaga-intruz!!!',0
    KASUJ5  DB      '     ',0              ;5 spacji
    
    do góry
© mgr inż. Piotr Kotarski, Kalety