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.