Serwis Edukacyjny w I-LO w Tarnowie ![]() Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Tłumaczenie: mgr Jerzy Wałaszek |
©2021 mgr Jerzy Wałaszek |
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.
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:
Asembler Z80 |
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.
Ł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 ASCII '$' (używany jako znak końca łańcucha) lub przesłania wszystkich 132 znaków. Operację wykonujemy następująco:
Asembler Z80 |
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.
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:
Asembler Z80 |
LD HL, DATA ; adres pierwszego bajtu |
Operacja wymaga 11 bajtów.
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:
Asembler Z80 |
LD HL, ARG1 ; adres odjemnej |
Operacja wymaga 17 bajtów.
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
|
![]() |
Zespół Przedmiotowy |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.