Assembler Zilog Z80 - lekcja pierwsza - rejestry / przenoszenie danych / arytmetyka
Całkiem niedawno załapałem się do pomocy przy zaliczeniach z assemblera na mikroprocesor Z80 w związku z czym chciałbym poruszyć kilka zagadnień związanych z programowaniem. Szczegóły techniczne pominę, bo sporo tego w sieci.
Rejestry
Zilog Z80 posiada kilkanaście rejestrów:
- rejestry 8 bitowe: A, B, C, D, E, H, L
- rejestry 16 bitowe złożone z dwóch 8 bitowych rejestrów: AF, BC, DE, HL, IY, IX, SP
- rejestry indeksowe: IY, IX
- rejestr flag: F
- rejestr wskaźnik stosu: SP
- rejestr wskaźnik aktualnej instrukcji: CP
Operowanie na danych
Pierwsze polecenie, które zamierzam omówić to LD. Jest to odpowiednik polecenia MOV w assemblerze x86. Dzięki temu poleceniu możemy ustawić dowolną wartość rejestru lub komórki pamięci. Niestety pocesor nie pozwala nam robić tego dowoli. I tak, możemy posłużyć się rejestrami BC i DE jako wskaźnikami do miejsca w pamięci by przenieść z niej wartość do rejestru A:
LD A, (BC) ; by zasygnalizować kompilatorowi, że zamierzamy użyć wskaźnika
LD A, (DE) ; stosujemy nawiasy: (rejestr) lub (stała)
Ale nie możemy już tego zrobić dla innych rejestrów:
LD A, (HL) ; nie zadziała!
LD A, (IY) ; nie zadziała!
Z powrotem natomiast mamy większe pole do popisy, bo z A możemy załadować wartość wskazując jej adres rejestrami: BC, DE i HL:
LD (BC), A ; przypisze wartość przechowywaną w A do miejsca wskazanego przez BC
LD (DE), A
LD (HL), A
Jeżeli zamieramy przypisać stałą, to możemy to robić dowoli z wyłączeniem rejestrów CP i F.
LD A, 32
LD H, 64
LD BC, 43 ; w tym wypadku rejestr C przyjmie wartość 43, a rejestr B wartość 0. Dzieje się tak ponieważ rejestr C jest rejestrem młodszym i przechowuje wartości do wartości maksymalnej 0xFF.
Możemy również załadować do rejestru wartość z innego rejestru:
LD A, 32
LD B, A
LD C, B
Nie możemy natomiast załadować rejestru 8 bitowego do jego 16 bitowego kolegi
LD BC, A ; nie zadziała!
LD HL, B ; nie zadziała!
By załadować dane ze stałej określającej offset (adres komórki pamięci) posłużymy się:
- rejestrem A dla danych 8 bitowych: LD A, (323)
- rejestrem HL dla danych 16 bitowych: LD HL, (534)
Jeśli natomiast chcemy umieścić wartość rejestru w offsecie wskazującym na konkretną komórkę pamięci, to mamy do dyspozycji szereg opcji:
LD (22), A
LD (13), HL
LD (43), IX
LD (65), IY
Rejestry IX oraz IY przydają się podczas indeksowania, gdy do adresu przechowywanego w jednym z rejestrów chcemy dodać stałą:
LD IY, 23
LD A, (IY+5)
Jeśli chcemy ustawić nową wartość wskaźnikowi stosu SP używamy rejestrów HL, IX i IY:
LD SP, HL
LD SP, IX
LD SP, IY
Arytmetyka
Procesor Z80 niestety nie potrafi mnożyć ani dzielić, ale miast tego umie dodawać i odejmować. Niestety znów nieudolnie.
Do rejestru A możemy dodać dowolny rejestr 8 bitowy lub 8 bitową stałą:
ADD A, 5
ADD A, B
Prócz tego możemy również dodać wartość znajdującą się w komórce pamięci:
ADD A, (HL)
ADD A, (IY+5)
ADD A, (IX+7)
Jeśli chodzi o operacje 16 bitowe to mamy większe pole do popisu:
- Do HL możemy dodać BC, DE, HL, SP
- Do IX możemy dodać BC, DE, IX, SP
- DO IY możemy dodać BC, DE, IY, SP
Jeśli chodzi o odejmowanie, to mamy do dyspozycji tylko rejestr A i odejmowanie stałych:
LD A, 54
SUB 5
Dlatego jeżeli zamierzamy odjąć liczbę przechowywaną w rejestrze lub odjąć liczbę od rejestru 16 bitowego, sugeruję odwrócić znak liczby, a następnie taką odwróconą liczbę dodać.
Proszę zważać na to co piszecie w komentarzach. Wpisy zawierające idiotyczne, obraźliwe, wulgarne, ubogie merytorycznie lub niezgodne z polskim prawem treści będą usuwane.