Przykłady Implementacji Sprzętowej i Programowej - Oprogramowanie


Przegląd własności programowych

Zestaw instrukcji Z80 udostępnia użytkownikowi dużą liczbę operacji do sterowania mikroprocesorem Z80. Rejestry główne oraz indeksowe mogą przechowywać wyniki operacji arytmetycznych i logicznych, tworzyć adresy pamięci lub grać rolę szybkiej, podręcznej pamięci na często używane dane.

Informację można przemieszczać bezpośrednio z rejestru do rejestru, z pamięci do pamięci, z pamięci do rejestrów oraz z rejestrów do pamięci. Dodatkowo zawartość rejestrów oraz zawartość innych rejestrów lub pamięci można ze sobą wymieniać bez konieczności rezerwowania tymczasowego miejsca na wymieniane dane. W szczególności można wymienić ze sobą zawartość głównych i pomocniczych rejestrów za pomocą jedynie dwóch instrukcji: EX i EXX. Taka wymiana rejestrów może być wykorzystywana do otrzymania rejestrów roboczych dla różnych procedur lub zwiększenia dostępnych rejestrów w pojedynczej procedurze.

Zachowywanie i odzyskiwanie danych dla par rejestrów lub komórek pamięci może być dokonywane metodą LIFO za pomocą instrukcji PUSH i POP, które wykorzystują rejestr WSKAŹNIKA STOSU (SP), Ten rejestr stosu jest udostępniony zarówno do manipulacji danymi jak i do zapisu i odczytu adresów powrotnych z procedur. Na przykład, gdy wywołana zostanie procedura, to adres następnej instrukcji za instrukcją CALL jest umieszczany na szczycie stosu adresowanego rejestrem SP. Gdy procedura wraca do wywołującego ją programu, adres ze szczytu stosu zostaje użyty do ustawienia licznika programu na adres tej następnej instrukcji. Wskaźnik stosu jest automatycznie korygowany tak, aby odzwierciedlał bieżący szczyt stosu podczas wykonywania instrukcji PUSH, POP, CALL i RET. Ten mechanizm pozwala umieszczać na stosie dane i adresy powrotu praktycznie do dowolnej głębokości zagnieżdżenia, ponieważ obszar stosu potencjalnie może być tak duży, jak duża jest dostępna przestrzeń pamięci.

Kolejność wykonywania instrukcji może być sterowana przy pomocy sześciu różnych znaczników (przeniesienie, zero, znak, parzystość/nadmiar, dodawanie/odejmowanie, przeniesienie połówkowe), które odzwierciedlają wyniki operacji arytmetycznych, logicznych, przesunięć i porównań.

Po wykonaniu instrukcji ustawiającej dany znacznik, może on zostać użyty jako warunek w instrukcji skoku lub powrotu z procedury. Instrukcje te udostępniają logiczną kontrolę nad przetwarzaniem pojedynczego bitu, bajtu lub słowa.

Dostępny jest pełny zestaw operacji logicznych AND, OR, XOR (exclusive-OR), CPL (NOR) i NEG (uzupełnienie do podstawy 2) dla działań logicznych pomiędzy akumulatorem a wszystkimi pozostałymi rejestrami 8 bitowymi, komórkami pamięci czy danymi bezpośrednimi.

Dodatkowo dostępny jest pełen zestaw przesunięć arytmetycznych i logicznych w obu kierunkach, który działa na zawartości wszystkich, głównych rejestrów 8 bitowych lub bezpośrednio na komórce pamięci. Znacznik przeniesienia może uczestniczyć lub być ustawiany w trakcie tych instrukcji przesunięć, aby udostępniać zarówno możliwość testowania wyników przesunięć jak również pozwalać na łączenie przesunięć w kilku rejestrach lub rejestrach i komórkach pamięci.

 

Przykłady specyficznych instrukcji Z80

Przykład nr 1:

Jeśli należy przemieścić w pamięci łańcuch danych o długości 737 bajtów spod adresu DATA do BUFFER, to operację tę programujemy następująco:

 

        LD   HL, DATA    ; adres startowy łańcucha danych
        LD   DE, BUFFER  ; adres startowy miejsca przeznaczenia danych
        LD   BC, 737     ; długość łańcucha
        LDIR             ; prześlij łańcuch - przemieść obszar pamięci wskazywany
       
                 ; przez HL do obszaru pamięci wskazywanego przez DE,
               
         ; zwiększ HL i DE, Zmniejsz BC i kontynuuj aż BC = 0.

 

Operacja ta wymaga 11 bajtów kodu, a każdy bajt danej jest przesyłany w ciągu 21 taktów zegara.

 

Przykład nr 2:

Łańcuch w pamięci (o długości ograniczonej do 132 znaków) umieszczony pod adresem DATA ma być przenoszony w inne miejsce pamięci o adresie BUFFER aż do momentu napotkania w tym łańcuchu na znak ASCI '$' (używany jako znak końca łańcucha) lub przesłania wszystkich 132 znaków. Operację wykonujemy następująco:

 

        LD   HL, DATA    ; adres początku łańcucha
        LD   DE, BUFFER  ; adres docelowego bufora
        LD   BC, 132     ; maksymalna długość łańcucha
        LD   A, '$'      ; kod zakończenia łańcucha
LOOP:   CP   (HL)        ; porównaj zawartość pamięci ze znakiem końca łańcucha
        JR   Z, END-$    ; idź na koniec, jeśli znak się zgadza
        LDI              ; przenieś znak spod (HL) do (DE)
                         ; zwiększ HL i DE, zmniejsz BC

        JP   PE, LOOP    ; wróć do LOOP, jeśli pozostało więcej znaków
END:    ...              ; inaczej przejdź do zakończenia.
                         ; Uwaga: znacznik P/V jest używany do informowania,
                         ; że BC osiągnął zero.

 

Operacja wymaga 19 bajtów kodu.

 

Przykład nr 3:

 


Rys.22 Przesuwanie cyfr BCD/bajtów

 

16 cyfrowa liczba dziesiętna jest przesuwana w sposób pokazany na rys.22. Te przesunięcie wykonuje się przy mnożeniu lub dzieleniu liczb BCD (ang. Binary Coded Decimal - liczby dziesiętne, gdzie każda cyfra kodowana jest na 4 bitach). 16 cyfrowa liczba dziesiętna jest zapisana w spakowanym formacie BCD (dwie cyfry BCD na bajt). Operację programuje się następująco:

 

        LD   HL, DATA    ; adres pierwszego bajtu
        LD   B, COUNT    ; licznik przesunięć
        XOR  A           ; wymaż akumulator
ROTAT:  RLD              ; obróć w lewo młodszą cyfrę w akumulatorze
                         ; z cyframi wskazywanymi przez (HL)

        INC  HL          ; przesuń wskaźnik
        DJNZ ROTAT-$     ; zmniejsz B i wróć do ROTAT, jeśli B jest większe od zera
                         ; inaczej przejdź do kolejnej instrukcji

 

Operacja wymaga 11 bajtów.

 

Przykład nr 4:

Jedna liczba ma być odjęta od drugiej i obie są w tym samym spakowanym formacie BCD, posiadając tą samą długość, która jednakże nie musi być stała. Wynik odejmowania ma być umieszczony w miejscu odjemnej. Operację programuje się następująco:

 

        LD   HL, ARG1    ; adres odjemnej
        LD   DE, ARG2    ; adres odjemnika
        LD   B, LENGTH   ; długość tych dwóch argumentów
        AND  A           ; zeruj znacznik przeniesienia
SUBDEC: LD   A, (DE)     ; odjemnik do A
        SBC  A, (HL)     ; odejmij (HL) od A
        DAA              ; popraw wynik na BCD
        LD   (HL), A     ; zachowaj wynik
        INC  HL          ; zwiększ wskaźniki pamięci
        INC  DE
        DJNZ SUBDEC-$    ; zmniejsz B i skocz do SUBDEC,
                         ; jeśli B jest różne od zera.
                         ; inaczej wykonaj kolejną instrukcję

 

Operacja wymaga 17 bajtów.

 

Przykłady zadań programistycznych

Przykładowy program z tablicy 2 sortuje ciąg liczb w porządku rosnącym za pomocą algorytmu standardowego sortowania bąbelkowego. Sortowane liczby posiadają zakres od 0 do 255.

 

Tablica 2. Listing programu sortowania bąbelkowego

Adres Kod
wynikowy
Wiersz Wiersz źródłowy
    1 ; standardowa procedura sortowania bąbelkowego
    2 ;  
    3 ; na wejściu:   HL zawiera adres danych
    4 ;               C zawiera liczbę elementów do sortowania
    5 ;               (1 < C < 256)
    6 ;  
    7 ; na wyjściu:   dane posortowane w porządku rosnącym
    8 ;  
    9 ; użycie rejestrów
    10 ;  
    11 ; rejestr   zawartość
    12 ;  
    13 ; A         przechowuje wyniki tymczasowe
    14 ; B         licznik ciągu danych
    15 ; C         długość ciągu danych
    16 ; D         pierwszy element porównania
    17 ; E         drugi element porównania
    18 ; H         znacznik informujący o zamianie
    19 ; L         nieużywany
    20 ; IX        wskaźnik ciągu danych
    21 ; IY        nieużywany
    22 ;  
0000 222600 23 SORT: LD   (DATA),HL   ; zachowaj adres danych
0003 CB84 24 LOOP: RES  FLAH,H      ; zeruj znacznik wymiany
0005 41 25   LD   B,C         ; ustaw licznik długości
0006 05 26   DEC  B           ; ustaw do testowania
0007 DD2A2600 27   LD   IX,(DATA)   ; ustaw wskaźnik danych
000B DD7E00 28 NEXT: LD   A,(IX)      ; pierwszy element do porównania
000E 57 29   LD   D,A         ; chwilowo zapamiętamy go w D
000F DD5E01 30   LD   E,(IX+1)    ; drugi element do porównania
0012 93 31   SUB  E           ; porównaj pierwszy z drugim
0013 3008 32   JR   PC,NOEX-$   ; jeśli pierwszy > drugi, skoku nie będzie
0015 DD7300 33   LD   (IX),E      ; zamień elementy ciągu
0018 DD7201 34   LD   (IX+1),D
001B CBC4 35   SET  FLAG,H      ; zapamiętaj, że była wymiana
001D DD23 36 NOEX: INC  IX          ; wskaż następny element danych
001F 10EA 37   DJNZ NEXT-$      ; zliczaj ilość porównań,
    38                    ; powtarza=j, jeśli pozostały pary danych
0021 CB44 39   BIT  FLAG,H      ; sprawdź, czy wystąpiła wymiana
0023 20DE 40   JR   NZ,LOOP-$   ; kontynuuj, jeśli dane nie są posortowane
0025 C9 41   RET              ; inaczej zakończ
    42 ;  
0026   43 FLAG: EQU  0           ; przydzielenie bitu znacznika
0026   44 DATA: DEFS 2           ; miejsce na adres danych
    45   END

 

Program z tablicy 3 mnoży dwie 16 bitowe liczby bez znaku, pozostawiając wynik w parze rejestrów HL.

 

Tablica 3. Listing programu mnożenia

Adres Kod
wynikowy
Wiersz Wiersz źródłowy
0000   1 ; mnożenie 16 bitowych liczb bez znaku
    2 ; na wejściu: mnożnik w DE
    3 ;             mnożna w HL
    4 ;  
    5 ; na wyjściu: wynik w HL
    6 ;  
    7 ; użycie rejestrów:
    8 ;  
    9 ;  
    10 ; H    starsze bity wyniku częściowego
    11 ; L    młodsze bity wyniku częściowego
    12 ; D    starsze bity mnożnej
    13 ; E    młodsze bity mnożnej
    14 ; B    licznik liczby przesunięć
    15 ; C    starsze bity mnożnika
    16 ; A    młodsze bity mnożnika
    17 ;  
0000 0610 18 MULT: LD   B,16       ; liczba bitów
0002 4A 19   LD   C,D        ; przenieś mnożnik
0003 7B 20   LD   A,E
0004 EB 21   EX   DE,HL      ; przenieś mnożną
0005 210000 22   LD   HL,0       ; wymaż wynik częściowy
0008 CB39 23 MLOOP: SRL  C          ; przesuń mnożnik w prawo
000A 1F 24   RRA             ; najmniej znaczący bit trafia
    25                   ; znacznika przeniesienia
000B 3001 26   JR   NC,NOADD-$ ; jeśli brak przeniesienia, pomiń dodawanie
000D 19 27   ADD  HL,DE      ; inaczej dodaj mnożną
    28                   ; do wyniku częściowego
000E EB 29 NOADD: EX   DE,HL      ; przesuń mnożną w lewo
000F 29 30   ADD  HL,HL      ; mnożąc ją przez dwa
0010 EB 31   EX   DE,HL
0011 10F5 32   DJNZ MLOOP-$    ; powtarzaj, aż do wykończenia bitów
0013 C9 33   RET
    34   END

 

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2018 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe