25_03.pdf

(199 KB) Pobierz
1128248 UNPDF
Też to potrafisz
Niniejszy, trzeci z kolei odcinek kursu
programowania poświęcony liście in−
strukcji procesora 8051, jest ostatnim
„teoretycznym” kawałkiem niezbęd−
nych informacji, dzięki którym wspólnie
krok po kroku utworzymy pierwszy
prawdziwy program.
Przy okazji pragnę wspomnieć że w lis−
tach napływających od Was drodzy Czy−
telnicy, często poruszacie sprawę niedo−
sytu wiedzy oraz informacji na temat
przytaczanych w lekcjach przykładów.
Otóż sprawa kompleksowego a jedno−
cześnie przystępnego przedstawienia
problemów związanych z programowa−
niem mikrokontrolerów nie jest taka
prosta, nawet z mego punktu widzenia.
Przekonałem się że nie da się w jednym
odcinku naszego cyklu przedstawić
wszystkich zagadnień użytych w jednej
z naszych lekcji. Zbyt wiele informacji
„zazębia” się za siebie, toteż proszę
o cierpliwość, wszystkie niejasne in−
strukcje z przykładów zostaną w kolej−
nym odcinku wyjaśnione do końca.
Mikrokontrolery?
To takie proste...
Część 9
Asembler – język maszynowy procesora
Jak wspominałem w poprzednim odcinku,
przyszła pora na zapoznanie się z ostatnią gru−
pą instrukcji, a mianowicie skokami oraz wy−
wołaniami podprogramów.
Pierwsze z nich dzielimy na:
– skoki warunkowe
– skoki bezwarunkowe
Dodatkowo, w przypadku skoków warun−
kowych, warunek przy którym następuje
skok, może spełniać określony bajt z we−
wnętrznej pamięci danych procesora (np. kie−
dy dany bajt
Argument taki zostaje w efekcie dodany do
licznika rozkazów PC, co w efekcie powoduje
skok do innej części programu – w przód lub
wtył.
Na początek poznajmy więc skoki warunko−
we testujące bity znajdujące się w obszarze
wew. RAM procesora, oczywiście.
Jak widać z przykładu korzystając z instrukcji
JC nie podawaliśmy argumentu bezpośred−
niego, czyli liczby, tylko określiliśmy za pomo−
ca etykiety „przenies” miejsce w programie
źródłowym do którego ma nastąpić skok, je−
żeli warunek będzie spełniony. Taki sposób
zapisu jest jak widać prostszy, nie musimy li−
czyć przesunięcia sami, które to jest zresztą
ilością bajtów kodu programu pomiędzy in−
strukcją skoku JC a miejscem skoku. Ta moż−
liwość dotyczy jednak tych z Was drodzy
Czytelnicy, którzy posiadają komputery i mo−
gą skorzystać z kompilatora zawartego na
dyskietce AVT–2250/D lub każdego innego.
W przypadku osób które „ręcznie” tłuma−
czą kod programu, sprawa się nieco kompli−
kuje, ale nie do tego stopnia, aby nie dać so−
bie z nią rady. W kolejnych lekcjach pokażę
jak prosto obliczać przesunięcia w tej in−
strukcji oraz pozostałych, tam gdzie wystę−
puje symbol „rel”, pamiętajcie o nim przy
lekturze dalszej części artykułu!
W tym miejscu istotna uwaga dla wszyst−
kich. Otóż jak widać wartość przesunięcia
nie może przekroczyć liczb z zakresu U2 czy−
li –128...127, innymi słowy skok względny
może odbyć się tylko w pewnym „otocze−
niu” (“w górę” lub „w dół”) od instrukcji
skoku. Jeżeli wartość przesunięcia jest
ujemna, to skok nastąpi oczywiście w kie−
runku mniejszych adresów (do PC zostaje
dodana liczba ujemna), w przeciwnym przy−
padku w kierunku adresów wzrastających.
W przypadku umieszczenia etykiety (miejs−
ca) skoku poza tym zakresem, prawidłowe
obliczenie przesunięcia będzie niemożliwe
(dla „ręczniaków”), a w przypadku korzysta−
nia z kompilatora 8051 (”komputerowcy”)
wystąpi komunikat o błędzie kompilacji mó−
wiący o przekroczeniu zakresu skoku
względnego. Programiście w takim przypad−
konkretna liczba to następuje
skok) lub bit. W tym ostatnim przypadku pro−
cesor sprawdza czy bit jest ustawiony (=1)
czy wyzerowany (=0) i podejmuje decyzję
o skoku lub nie. A co może w programie
zmienić takim czy inny bit?, a no jakaś in−
strukcja która została wykonana wcześniej,
a wyniku której dany bit został ustawiony lub
wyzerowany. W języku programistów bit (bi−
ty), którego znaczenie jest istotne dla działa−
nia programu, który informują o tym czy, np.
przy dodawaniu dwóch liczb 8–bitowych na−
stąpiło przeniesienie (kiedy wynik > 255), na−
zywa się „flagą”. Określeniem tym będziemy
się dość często posługiwać, toteż warto je
zapamiętać.
Warto też sobie wyjaśnić co oznacza samo
pojęcie skoku fizycznie dla pracy procesora.
Otóż jeżeli procesor wykonuje kolejne instruk−
cje programu, to za każdym pobraniem kolej−
nej instrukcji zwiększa się automatycznie licz−
nik rozkazów PC, o którym mówiliśmy już
wcześniej. Jeżeli procesor napotka na instruk−
cję skoku, to argumentem (tej instrukcji) w ta−
kim przypadku, jest liczba będąca:
– przesunięciem (liczba w kodzie U2, zakres
<–128...127>, która jest dodawana do bie−
żącej wartości PC
lub
– wartością bezwzględną licznika rozkazów
PC (w przypadku skoków bezwarunkowych)
JC rel
– ang.”jump if Carry” – skocz jeżeli znacznik
przeniesienia C jest ustawiony
– sprawdzany jest bit przeniesienia C w sło−
wie PSW (adres bajtu: D0h), jeżeli jest usta−
wiony (=1) to do licznika rozkazów PC jest
dodawana 8–bitowa liczba „rel” (zapisana
w kodzie U2), zostaje wykonany skok
względny
PC <– PC + 2, jeśli C=1, to PC <– PC + rel
– kod: 01000000 40h
– cykle: 2 bajty: 2 (kod instrukcji 40h
+ przesunięcie „rel”)
– przykład:
MOV A,#20h ;załadowanie do
akumulatora liczby 32
ADD A,B ;dodanie do
akumulatora bieżącej
wartości rej. B
JC przenies ;czy nastąpiło
przeniesienie, tak to skocz do
etykiety
;”przenies”
MOV B,#0
;nie, to wyzeruj rejestr B
.....
;po czym wykonuj dalsze
instrukcje
.....
.....
przenies:
;tu nastapi skok jeżeli
znacznik C był ustawiony
CLR C
;w efekcie nastąpi jego
wyzerowanie
E LEKTRONIKA DLA WSZYSTKICH 1/98
41
1128248.002.png
Też to potrafisz
ku nie pozostaje nic innego jak poprawić
błąd modyfikując program źródłowy.
można zrealizować pętlę nieskończoną
(„zawiesić” procesor), używając instrukcji
skoku warunkowego. Zauważmy przecież,
że warunek: że bit 70h jest wyzerowany bę−
dzie spełniony zawsze, toteż za każdym ra−
zem nastąpi skok do etykiety „zeruj”
w miejsce programu gdzie następuje zero−
wanie bitu 70h, i cała pętla się powtarza.
......
;instrukcje programu
......
;tu zaczyna się podprogram, którego (w tym
przykładzie) zadaniem jest wysłanie
;poprzez końcówki portu P1 procesora sek−
wencji kodów ASCII odpowiadających
;kolejnym literom tekstu „Hello from AVT−
–2250”, aż do momentu napotkania kodu
;zerowego (“0”).
JNC rel
– ang.”jump if not Carry” – skocz jeżeli znacz−
nik przeniesienia C jest wyzerowany
– sprawdzany jest bit przeniesienia C w sło−
wie PSW (adres bajtu: D0h), jeżeli jest wy−
zerowany (=0) to do licznika rozkazów PC
jest dodawana 8–bitowa liczba „rel” (zapi−
sana w kodzie U2), zostaje wykonany skok
względny
PC <– PC + 2, jeśli C=0, to PC <– PC + rel
– kod: 01010000 50h
– cykle: 2 bajty: 2 (kod instrukcji 50h
+ przesunięcie „rel”)
– przykład:
MOV A,#20h ;załadowanie do
akumulatora liczby 32
JBC bit, rel
– ang.”jump if Bit Set and Clear Bit ” – skocz
jeżeli bit jest ustawiony i wyzeruj go
– sprawdzany jest bit, którego adres podany jest
w „bit”, jeżeli jest ustawiony (=1) to zostaje wy−
zerowany po czym do licznika rozkazów PC jest
dodawana 8–bitowa liczba „rel” (zapisana w ko−
dzie U2), zostaje wykonany skok względny
PC <– PC + 3, jeśli (bit)=1, to (bit)<–0
i PC <– PC + rel
– kod: 0 0 0 1 0 0 0 0 10h
– cykle: 2 bajty: 3 (kod instrukcji 10h
+ adres bitu + przesunięcie „rel”)
– przykład: wykonanie sekwencji instrukcji
ADD A, B
PISZ: ;etykieta – nazwa
podprogramu
MOV DPTR, #tekst
;załaduj do wskaź
nika DPTR
adres tesktu
next:
CLR A ;wyzeruj akumulator
MOVC A,@A+DPTR
;pobierz kolejny
znak z tekstu
(do akumulatora)
dodaj:
ADD A,#1
;dodanie do akumulatora
liczby 1
JZ
koniec ;czy koniec tekstu ( znak
= Acc = 0 )?, tak to skocz
MOV P1, A
;nie to wyślij kod na koń−
cówki portu P1
JNC dodaj
;czy nastąpiło przeniesie
nie, nie to dodaj jeszcze raz
;dodaj do akumulatora
zawartość rejestru B
INC
DPTR
;przesuń adres na kolejną
literę tekstu
.....
;w efekcie akumulator będzie
inkrementowany aż do
JBC
C, et01 ;jeżeli nastąpiło przeniesienie
to wyzeruj C i skocz
SJMP next
;i skocz do „next” aby
pobrać kolejną literę
.....
;czasu kiedy osiągnie
wartość 00h, a do
znacznika C
;zostanie wpisana „1”–ka,
potem zostaną wykonane
.....
;jeżeli nie to wykonuj
dalsze instrukcje
koniec:
RET ;instrukcja zakończenia
podprogramu i powrotu do
;głównej części programu
;a to jest zdefiniowany przykładowy tekst,
zakończony kodem (bajtem) „0”
;w celu identyfikacji końca tekstu.
tekst
.....
et01:
MOV P1, A ;tu nastąpi skok jeżeli było
przeniesienie
funkcjonalnie jest równoważne sekwencji:
ADD A, B
.....
;dalsze instrukcje
JB bit, rel
– ang.”jump if Bit Set” – skocz jeżeli bit jest
ustawiony
– sprawdzany jest bit, którego adres podany
jest w „bit”, jeżeli jest ustawiony (=1) to do
licznika rozkazów PC jest dodawana 8–bito−
wa liczba „rel” (zapisana w kodzie U2), zo−
staje wykonany skok względny
PC <– PC + 3, jeśli (bit)=1, to PC <– PC + rel
– kod: 00100000
;dodaj do akumulatora
zawartość rejestru B
DB‘ HELLO FROM AVT–2250, 0
JC
et01
;jeżeli nastąpiło
przeniesienie skocz
LCALL adr16
– ang. „subroutine call” – skocz do podpro−
gramu
– licznik rozkazów PC zostaje zwiększony o 3,
jest ładowany na stos w efekcie czego
wskaźnik stosu jest zwiększany o 2, a do
licznika rozkazów PC zostaje wpisany
16–bitowy adres bezpośredni, podany jako argu−
ment przy wywołaniu instrukcji „LCALL”. Dzięki
tej instrukcji możliwe jest wywołanie podprogra−
mu w dowolnym obszarze pamięci (64kB) po−
przez podanie bezpośredniego adresu.
PC <– PC + 3
SP <– SP + 1, (SP) <– PC 7–0 ,
SP <– SP + 1, (SP) <– PC 15–8
PC <– adr16
– kod: 00010010 12h
– cykle: 2 bajty: 3 (kod instrukcji
12h + bardziej znaczący bajt „adr16”
+ mniej znaczący bajt „adr16”
– przykład: wypisanie liczby 12h na wyświet−
laczu komputerka edukacyjnego przy pomo−
cy instrukcji A2HEX standardowo umiesz−
czonej w kodzie monitora systemu (w EP−
ROM dołączonej do zestawu).
A2HEX EQU 024Eh ;deklaracja
adresu podpro−
gramu w
monitorze
MOV A, #12h ;wypisz liczbę
12h jako 2 znaki
w HEX
MOV B, #3 ;na pozycji
3 wyświetlacza
LCALL A2HEX ;pod adresem
024Eh znajduje
się gotowy
;podprogram do wypisywania
akumulatora w
;postaci 2 cyfr HEX
W efekcie wykonania przykładu na wy−
świetlaczach zostanie wypisana liczba 12h.
W postaci „12”.
.....
;jeżeli nie to wykonuj
dalsze instrukcje
......
et01:
CLR C
20h
;tu nastąpi skok jeżeli było
przeniesienie, zeruj C
– cykle: 2
bajty: 3 (kod instrukcji 20h
+ adres bitu +
przesunięcie „rel”)
MOV P1,A
przeanalizuj i zastanów się dlaczego?
– przykład:
JB
7Fh, zeruj ;jeżeli bit o adresie 7Fh = 1
to skocz do etykiety „zeruj”
To tyle jeżeli chodzi o skoki warunkowe
operujące na bitach, teraz pora na kilka in−
strukcji skoków warunkowych operujących
na bajtach, bezwzględnych oraz wywołań
podprogramów.
MOV A,B
;jeśli nie to dodaj do
akumulatora rejestr B
.....
;i wykonuj dalsze instrukcje
.....
zeruj:
CLR A
;jeżeli bit był ustawiony to
wyzeruj akumulator
ACALL adr11
– ang. „subroutine call on page”, skocz do
podprogramu na stronie
– licznik rozkazów PC jest zwiększany o 2, na−
stępnie ładowany jest na stos (najpierw
młodszy bajt, potem starszy), wskaźnik stosu
jest zwiększany o 2, a do bitów 0...10 liczni−
ka PC zostaje wpisany 11–bitowy adres bez−
pośredni podany jako argument instrukcji:
„adr11”. Pięć najstarszych bitów licznika roz−
kazów PC nie ulega zmianie, toteż skok zo−
staje wykonany w obrębie 2 kilobajtowej
„strony” pamięci programu, na której wystę−
puje następna po „ACALL adr11” instrukcja.
PC <– PC + 2,
SP <– SP + 1, (SP) <– PC 7–0 ,
SP <– SP + 1, (SP) <– PC 15–8
PC 10–0 <– adr11
– kod: a10 a9 a8 1 0001
gdzie: a10, a9, a8 zależą od numeru strony
stąd: 11h, 31h, 51h, 71h, 91h, B1h, D1h, F1h
– cykle: 2 bajty: 2 (kod instrukcji
+ młodszy bajt adresu „adr11” – bity a7...a0)
– przykład:
ACALL PISZ
JNB bit, rel
– ang.”jump if Bit not Set” – skocz jeżeli bit
jest wyzerowany
– sprawdzany jest bit, którego adres podany
jest w „bit”, jeżeli jest wyzerowany (=0) to
do licznika rozkazów PC jest dodawana
8–bitowa liczba „rel” (zapisana w kodzie
U2), zostaje wykonany skok względny
PC <– PC + 3, jeśli C=0, to PC <– PC + rel
– kod: 00110000 30h
– cykle: 2 bajty: 3 (kod instrukcji 30h
+ bajt + przesunięcie „rel”)
– przykład:
CLR C
;wyzerowanie znacznika
przeniesienia
zeruj:
MOV 70h, C ;wyzerowanie bitu
a adresie 70h
JNB 70h,zeruj ;jeżeli bit 70h jest =0 to
skok do etykiety „zeruj”
Podany przykład, z praktycznego punktu wi−
dzenia jest nieprzydatny, lecz pokazuje jak
;wywołanie podprogramu
......
;po zakończeniu go
zostają wykonane kolejne
42
E LEKTRONIKA DLA WSZYSTKICH 1/98
1128248.003.png
Też to potrafisz
RET
– ang. „return from subroutine”, powróć
z podprogramu
– adres powrotu z podprogramu (zapamiętana
wcześniej podczas instrukcji ACALL lub
LCALL wartość licznika PC) jest wpisywany
do licznika rozkazów PC. Wskaźnik stosu zo−
staje mniejszony o 2. W efekcie następuje
powrót z podprogramu. Instrukcją tą musi
kończyć się każdy podprogram (z wyjątkiem
podprogramów obsługi przerwań, wywoły−
wanych automatycznie przez procesor).
PC 15–8 <– (SP), SP <– SP – 1
PC 7–0 , <– (SP), SP <– SP – 1
– kod: 00100010
wołania instrukcji SJMP. W tym przypadku ar−
gumentem instrukcji jest przesunięcie (tak jak
wspominany wczesniej parametr „rel” przy
okazji omawiania insturkcji skoków warunko−
wych operujących na bitach), wyrażone po−
przez liczbę 8–bitowa zapisaną w kodzie U2.
– na stronie (instrukcja AJMP – „absolute jump
on page”), gdzie skok może nastapić w obsza−
rze 2 kilobajtowej strony. W tym przypakdu ar−
gumentem instukcji jest 11–bitowy adres bez−
pośredni, który podajemy po mnemoniku
AJMP. W praktyce można ten skok określić ja−
ko „średni” (w stosunku do krótkiego SJMP)
– długi (instrukcja LJMP – „long jump”), gdzie
skok może nastapić w dowolne miejsce
w obszarze 64kB przestrzeni pamięci progra−
mu procesora. W tym przypadku argumen−
tem skoku jest 16–bitowy adres bezpośred−
ni podawany jako argument tej instrukcji.
stąd: 01h, 21h, 41h, 61h, 81h, A1h,
C1h, E1h
– cykle: 2
bajty: 2 (kod instrukcji
+ młodszy bajt adresu
„adr11” – bity a7...a0)
– przykład:
MOV
P1,A
AJMP
koniec
.....
.....
.....
koniec:
22h
Po przesłaniu zawartości akumulatora do por−
tu P1 (na końcówki tego portu) procesor omi−
nie instrukcje w liniach oznaczonych wielo−
kropkiem i wykona skok do miejsca (etykie−
ty) programu oznaczonej jako „koniec”.
– cykle: 2 bajty: 1
– przykład: patrz procedura „PISZ” przy okaz−
ji omawiania instrukcji ACALL. Procedura
„PISZ” została zakończona instrukcją po−
wrotu z podprogramu „RET”, dzięki której
mogło nastąpić odtworzenie pierwotnego
stanu licznika PC i dzięki temu powrót do
programu głównego. Tak powinien kończyć
się każdy Twój podprogram.
Ktoś może w tym miejscu zapytać, „po co
ta komplikacja, przecież wystarczyłby w za−
sadzie tylko jeden typ skoku, taki który daje
największe możliwości, czyli LJMP?”. Tak
ale w przypadku pisania programów na pro−
cesory jednoukładowe istnieje potwierdzo−
na w praktyce zasada, że: „każdy bajt kodu
jest cenny, toteż program należy pisać tak
aby zajmował jak najmniej miejsca”. I tu le−
ży sedno sprawy, otóż trzy wymienione ro−
dzaje instrukcji skoków różnią sie objętością
zajmowaną w kodzie programu. I tak skok
krótki SJMP oraz na stronie AJMP zajmuja
2 bajty kodu, natomiast skok długi LJMP za−
jmuje 3 bajty, ktoś powie że to mała różnica,
otóz moi drodzy będziecie mogli się o tym
jeszcze przekonać że często 1 dodatkowy
bajt wolny w programie to recepta na zreali−
zowanie i dokończenie niejednego progra−
mu. Przejdźmy zatem do szczegółow.
SJMP rel
– ang. „Shot Jump” – skok bezwarunkowy
krótki
– do zawartości licznika rozkazów PC jest do−
dawane 8–bitowe przesunięcie (liczba ze
znakiem w kodzie U2 z zakresu
<–128...127>). W efekcie wykonywany jest
skok w obrębie 256 bajtów od kolejnej po
SJMP instrukcji.
PC <– PC + 2, PC <– PC + rel
– kod: 10000000
RETI
– ang. „return from interrupt”, powróć z pod−
programu obsługi przerwania
– adres powrotu z podprogramu obsługi prze−
rwania jest wpisywany do licznika rozkazów
PC. Wskaźnik stosu zostaje mniejszony o 2.
Instrukcją tą musi kończyć się każdy pod−
program, który jest wywoływany automa−
tycznie przez procesor w przypadku zgło−
szenia przerwania i żądania jego obsługi.
PC 15–8 <– (SP), SP <– SP – 1
PC 7–0 , <– (SP), SP <– SP – 1
– kod: 00110010
80h
– cykle: 2
bajty: 2 (kod instrukcji 80h
+ przesunięcie „rel”)
– przykład:
MOV A,B
;dowolne insturkcje
programu
CLR B
;——−−−−−−−− „” ————
.....
stop:
SJMP stop
32h
– cykle: 2 bajty: 1
– przykład: omówimy przy okazji dokładnego
opisu systemu przerwań oraz możliwości
praktycznych zastosowań.
;i przykład pętli
nieskończonej, którą
powinien dla
;bezpieczeństwa kończyć
się każdy program
AJMP adr11
– ang. „Absolute Jump”, skocz bezwarunko−
wo na stronie
– licznik rozkazów zostaje zwiększony o 2, na−
stępnie do jego bitów 0–10 zostaje wpisany 11−
–bitowy adres bezpośredni podany jako para−
metr. Pozostałe 5 bardziej znaczących bitów nie
zmienia się. W efekcie wykonania tego polece−
nia następuje skok pod adres na stronie pamię−
ci programu o wielkości 2 kilobajty, na której
jest umieszczona kolejna instrukcja po AJMP.
PC 10–0 <– adr11
– kod: a10 a9 a8 0 0 0 0 1 ,gdzie: a10, a9,
a8 zależą od
numeru strony
Teraz zapoznam Was, drodzy Czytelnicy
z trzema bardzo często używanymi instruk−
cjami skoków bezwarunkowych. W liście in−
strukcji procesora 8051 istnieją trzy rodzaje
instrukcji skoku bezwarunkowego. Róznica
między nimi polega na „odległości” (o ile
bajtów programu dalej można skoczyć) po−
między instrukcją skoku a miejscem w któ−
re następuje skok. I tak mamy do czynienia
ze skokiem :
– krótkim (instrukcja SJMP – „short jump”),
gdzie skoczyć możemy w obrębie 256 bajtów
(w góre o 127 lub w dół o 128) od miejsca wy−
END
;deklaracja końca
programu (to nie jest
instrukcja!)
A oto pozostałe instrukcje skoków, jedna
bezwarunkowa oraz pozostałe warunkowe
sprawdzające warunek równości bajtu o po−
danym adresie lub rejestru z innym bajtem
lub argumentem bezpośrenim.
Dokończenie listy instrukcji w następnym
numerze.
Sławomir Surowiński
Lekcja 4
W dzisiejszej lekcji poćwiczymy sobie użycie
niektórych z przedstawionych instrukcji wywo−
łań podprogramów. Na wstępie jednak kilka
wyjaśnień. Otóż jak zdążyliście się zorientować
z poprzednich lekcji w przykładach podawałem
listingi programów, w których występowały in−
strukcje wywołań „dziwnych” procedur np.
LCALL A2HEX
ROM zawarty jest program monitora – o tym
już wiecie. Dzięki niemu możliwa jest komuni−
kacja i ładowanie programów z komputera PC
lub ręcznie. Monitor jest na tyle mądry że do−
datkowo komunikuje się z użytkownikiem za
pomocą 8–mio pozycyjnego wyświetlacza i lo−
kalnej klawiatury. No ale przecież ten „moni−
tor” to w końcu też kawałek programu napisa−
ny za pomocą tych samych instrukcji , które
poznawaliście przez ostatnie 3 odcinki nasze−
go kursu. To właśnie dzięki niemu całe urzą−
dzenie żyje i pozwala na niezłą zabawę.
Oprócz zawartych w monitorze funkcji uak−
tywnianych klawiszami np. „LOAD”, „EDIT”,
itp. istnieje kilka bardzo użytecznych procedur
które są potrzebne no chociażby do wypisania
aktualnej wartości rejestru DPTR na wyświet−
laczu (tak się dzieje np., przy edycji pamięci
RAM kiedy na 4 pierwszych wyświetlaczach
DPTR jest wyświetlany jako 4 znaki w kodzie
szesnastkowym.
A czy zastanawiałeś się drogi Czytelniku,
jak to się dzieje, że po naciśnięciu przez Cie−
bie odpowiedniego klawisza, układ reaguje
lub
LCALL CLS (2)
Otóż moi drodzy w programie monitora któ−
ry macie w swoim komputerku w pamięci EP−
E LEKTRONIKA DLA WSZYSTKICH 1/98
43
(1)
1128248.004.png
Też to potrafisz
np. uaktywniając odpowiednią funkcję moni−
tora? Do tego celu wykorzystywany jest inny
podprogram (także zawarty w monitorze) któ−
rego zadaniem jest oczekiwanie na naciśnię−
cie klawisza a następnie podjęcie decyzji „co
z tym fantem dalej robić...”. Takie przykłady
można by mnożyć.
Ja w każdym razie w kolejnym odcinku
przedstawię Ci pełną listę dodatkowych pro−
cedur (podprogramów) które będą niezmier−
nie przydatne przy tworzeniu wspólnych pro−
gramów.
Ci z „komputerowców”, którzy już nabyli
dyskietkę AVT2250/D mogą zapoznać się z ta−
ką listą czytając zbiór „BIOS.INC”, w którym
są zawarte definicje adresów wszystkich po−
trzebnych procedur . Dodatkowo umieszczo−
no w nich opis i sposób wywołania, czyli para−
metry wejściowe podprogramu, oraz efekt
działania.
Pamiiętajj,, wszystkiie one są częściią progra−
mu moniitora ii tak samo jjak napiisany przez Ciie−
biie program są ciiągiiem określlonych iinstrukcjjii,,
w wyniiku dziiałłaniia których otrzymujjesz okreś−
llony efekt,, np.. na wyświietllaczu..
Ze względu na ograniczona objętość artyku−
łu, w dzisiejszej lekcji wykorzystamy tylko nie−
które procedury (podprogramy).
Dla przykładu skorzystajmy z podprogramu
którego zadaniem jest wypisanie na wyświet−
laczu na pozycji określonej w rejestrze B, licz−
by znajdującej się w akumulatorze w postaci
heksadecymalnej (szesnastkowej). Procedu−
ra ta znajduje się w monitorze pod adresem
024Eh.
Ciekawa jest też procedura CLS – w wyniku
wykonania jej całe pole odczytowe zostaje wy−
czyszczone. Adres tego podprogramu w moni−
torze to 0274h. Procedura ta jest bezparamet−
rowa, wystarczy ją wywołać aby uzyskać za−
mierzony efekt.
zawarty jest przetłumaczony kod (tekst pogru−
biony) niezbędny dla „ręczniaków” – przetłu−
maczcie sami i porównajcie wynik!
Przyjrzyjmy się listingowi dokładnie i przea−
nalizujmy go linia po linii. Dla uproszczenia bę−
dę używał dodatkowych oznaczenia (K)
w przypadku gdy linia ma znaczenie tylko dla
„komputerowców”, oraz (R) gdy linia ma zna−
czenie dla „ręczniaków”. gdy nie występuje
żadne z oznaczeń, informacja jest istotna dla
wszystkich. A więc zaczynamy (Lx – numer li−
nii, np. L4 – linia nr 4)
L1: (K), deklaracja zbioru który zawiera nie−
zbędne definicje rejestrów procesora 8052 (a
także 8051 oczywiście)
L2: deklaracja EQU – równoważności, ozna−
cza że w dalszej części programu słowo „licz−
ba” jest równoważne (literowo) wyrażeniu
„45h”, a 45h to zapisana w kodzie szesnastko−
wym liczba.
L3: deklaracja EQU – podobnie jak poprzed−
nio, tym razem słowo „pozycja” będzie ozna−
czało wyrażenie „3”, u nas jest to numer po−
zycji na wyświetlaczu, na której ma być wy−
świetlona 2–pozycyjna liczba z akumulatora.
L4: deklaracja ORG – nakazuje kompilatoro−
wi (K) przetłumaczenie (kompilację) instrukcji
występujących po tej deklaracji począwszy od
adresu wskazanego w parametrze ORG, czyli
w naszym przypadku będzie to 8000h – począ−
tek zewnętrznej pamięci w komputerku edu−
kacyjnym. Dla „ręczniaków” jest to informacja
aby wprowadzać kod programu (pogrubiony
tekst) od adresu 8000h korzystając oczywiście
z funkcji „EDIT” komputerka.
czyli wspomniana liczba 45h – prawda że się
zgadza!
L7: musimy także powiedzieć procedurze
A2HEX, żeby wyświetliła liczbę od pozycji 3 na
displeju, toteż ładujemy jako drugi parametr
„pozycję” (która oznacza po prostu „3”)..
Uff!
L8: wreszcie właściwe wywołanie podpro−
gramu A2HEX. „Ręczniacy” będą musieli wpi−
sać adres bezpośredni procedury, który poda−
łem wcześniej, stąd w linii po lewej stronie lis−
tingu mamy sekwencję kodu: 12 02 4E, pierw−
sza liczba to kod instrukcji LCALL, następne
dwie to adres procedury A2HEX – sprawdź!
W efekcie po wykonaniu tego podprogramu
na wyświetlaczach DL3 i DL4 pojawi się liczba
„45”, czyli to co chcieliśmy!
L8: tu mamy omawiany przy okazji prezen−
towania instrukcji skoków bezwarunkowych,
przykład instrukcji SJMP , która została użyta
do zatrzymania programu. Instrukcja użyta
w ten sposób spowoduje że procesor będzie
skakał w kółko pod adres etykiety „stop”, czy−
li pod adres pod którym znajduje się instrukcja
SJMP ... „i tak w koło Macieju...”, w efekcie
można powiedzieć że program będzie krążył
w pętli nieskończonej, i tylko klawisz „M”
– powrotu do monitora może nas wybawić
z tego ślepego zaułka.
Ktoś może powiedzieć, „.... ale po co właś−
ciwie ta instrukcja SJMP, przecież i tak to już
koniec programu...”.
Koniec dla nas drodzy Czytelnicy, my o tym
doskonale wiemy, bo takie było założenie, ale
biedny procesor, kiedy wróci z podprogramu
A2HEX, będzie „pożerał” kolejne bajty kodu
programu, i jeżeli nie napotka na sensowne za−
kończenie w pętli nieskończonej (jak w przy−
kładzie) zacznie pobierać kolejne bajty progra−
my spoza adresu 800Dh, a tam co jest?, a no
same „śmieci” Kochani – sprawdźcie to fun−
kcją EDIT monitora.
Stąd zaczyna się prawdziwa część programu.
L5: dobrze by było aby po rozpoczęciu wy−
konywania naszego programu wyświetlacz nie
był zapisany jakimiś znakami, zupełnie nam
niepotrzebnymi. W tym celu profilaktyczne
wywołujemy podprogram CLS – czyszczący
wyświetlacz.
L6: do akumulatora zostaje załadowana licz−
ba do wyświetlenia, tym razem jest to liczba
45h. Te polecenie można zapisać także jako:
„ mov A, #45h ”.
„Ręczniacy” tak będą musieli postąpić, bo−
wiem nie korzystają z mądrego kompilatora,
Zadanie
Wypisać dowolną 8–bitową liczbę na wy−
świetlaczu w postaci heksadecymalnej.
Załóżmy że chcemy aby liczba pojawiła się
na 3–ciej i 4–tej pozycji, należy wykonać
i skompilować (komputerowo lub ręcznie prze−
tłumaczyć) instrukcje:
Nie musze tłumaczyć, co się wtedy może
stać. Nielogiczna sekwencja bajtów spowodu−
je niekontrolowane działanie procesora,
w efekcie czego najprawdopodobniej układ
dojdzie do końca pamięci programu FFFFh po
czym licznik rozkazów PC zostanie wyzerowa−
ny a w związku z tym na wyświetlaczu zoba−
czymy znajomy napis „HELLO”, oznajmiający
nam że właśnie zrestartowaliśmy nasz kompu−
terek. Dodatkowo stanie się to tak szybko że
efekt naszej pracy zostanie nie zauważony
przez nasze czujne oko.
Dlatego stosowanie na końcu programu
takiego skoku jest wskazane w każdym przy−
padku.
No dobrze skoro wiecie o co chodzi, to ra−
dzę poeksperymentować z innymi wartościa−
mi akumulatora oraz zmieniać np. pozycję wy−
świetlania, pamiętając że może ona zawierać
się w granicach 1...7.
CPU
8052.DEF
0045
liczba equ
45h
;liczba do wyswietlenia
0003
pozycja equ
3
;pozycja na ktorej ma byc
;wyswietlona liczba
8000
org
8000h
8000 120274
lcall
CLS
;wyczyszczenie wyswietlacza
8003 7445
mov
A, #liczba
;zaladowanie liczby
8005 75F003
mov
B, #pozycja
;i pozycji na displeju
8008 12024E
lcall
A2HEX
;wyswietlenie
800B 80FE stop:
sjmp
stop
;stop programu
W kolejnej lekcji omówię wszystkie pozo−
stałe procedury dostępne w monitorze oraz
podam ich adresy wywołań, wtedy będziemy
modli naprawdę „poszaleć”. Nabywcy dyskie−
tek AVT2250/D mogą się z nimi już teraz za−
poznać czytając zbiory BIOS.INC i CONST.INC.
800D
END
Pamiętajmy, że jest to listing programu, czy−
li że komputerowcy wpisują tylko deklaracje
i instrukcje wraz z ewentualnymi komentarza−
mi (po średniku), bez pierwszej kolumny liczb
określającej adres bieżącej instrukcji (tekst po−
chyły), oraz bez drugiej kolumny liczb w której
który wie że od momentu deklaracji w linii
2 (L2) słowo „liczba” oznacza „45h”. Popatrz−
cie zresztą na kod tej linii po lewej stronie (po−
grubione liczby) – 7445 = 74 45, pierwsza to
kod instrukcji „mov A, #dana ”(patrz wkładka
z tabelą instrukcji 8051), druga to argument,
Wesołej zabawy!
Sławomir Surowiński
44
E LEKTRONIKA DLA WSZYSTKICH 1/98
1128248.005.png
Też to potrafisz
Też to potrafisz
instrukcje
.....
.....
jest_zero:
JMP @A+DPTR
– ang. „Jump Indirect relative to DPTR” –
skocz pośrednio względem rejestru DPTR
– w wyniku tej instrukcji następuje skok pod
adres będący sumą aktualnej wartości re−
jestru DPTR (liczba 16–bitowa) i wartości
akumulatora (liczba 8–bitowa). Można po−
wiedzieć że skok następuje pod adres w pa−
mięci programu umieszczony w DPTR
z przesunięciem podanym w akumulatorze.
Przesuniecie to traktowane jest jako liczba
bez znaku, czyli z zakresu <0...255>
PC <– A + DPTR
– kod: 01110011
etyk02:
;właściwe miejsce skoku
według pozycji = 1
;tu nastapi skok jeżeli
rej.B był równy zero
.....
etyk03:
;właściwe miejsce skoku
według pozycji = 2
.....
;i zostaną wykonane te
instrukcje
.....
etyk04:
.....
;właściwe miejsce skoku
według pozycji = 3
JNZ rel
– ang. „Jump if Accumulator is Not Zero”,
skocz jeżeli akumulator nie jest = 0 (zero)
– sprawdzana jest zawartość akumulatora (A),
jeżeli jest różna od zera, to do licznika rozka−
zów PC dodawane jest przesunięcie „rel” –
na zasadach takich jak opisano wczesniej
przy okazji omawiania poprzednich instrukcji
skoków z argumentem „rel” (liczba 8–bito−
wa ze znakiem w kodzie U2).
PC <– PC + 2, jeśli A <> 0, to PC <– PC + rel
– kod: 01110000
.....
73h
Poniżej zapoznamy się z instrukcjami sko−
ków warunkowych, które badają warunek
zgodności zadanego bajtu w wew. RAM
procesora (rejestru) z innym rejestrem lub
argumentem bezpośrednim (liczbą). Dwie
z nich JZ i JNZ sprawdzają czy w akumula−
torze znajduje się liczba zero czy nie i na tej
podstawie podejmowana jest decyzja
o skoku. Pozostałe instrukcje porównujące
wybrane rejestry z innym lub konkretną licz−
bą znajdują zastosowanie szczególnie
w pętlach programowych, gdzie konieczne
jest wykonanie n–razy określonej opracji.
– cykle: 2 bajty: 1
– przykład: realizacja skoków w miejsca
w programie określone poprzez numer
w zmiennej „pozycja” (umieszczonej – za−
deklarowanej z wewn. RAM procesora)
MOV A, pozycja ;załadowanie
numeru pozycji
MOV B, #2 ;2 bo instrukcje w tabeli
skoków sa 2–bajtowe
(AJMP)
MUL A, B ;obliczenie faktycznego
ofsetu do tabeli skoków
MOV DPTR, #tablica_skokow
;załadowanie adresu
tabeli skoków do DPTR
JMP @A+DPTR;wykonanie skoku
tablica_skoków: ;tu zaczyna sie tabela
skoków
AJMP etyk01 ;tu nastapi skok gdy
„pozycja” = 0
AJMP etyk02 ;tu nastąpi skok gdy
„pozycja” = 1
AJMP etyk03 ;tu nastąpi skok gdy
„pozycja” = 2
AJMP etyk04 ;tu nastąpi skok gdy
„pozycja” = 3
70h
– cykle: 2
bajty: 2 (kod instrukcji 70h
+ przesuenięcie „rel”)
– przykład:
MOV A, B ;załadowanie rej. B do
Acc celem sprawdzenia
czy = 0
JNZ nie_zero ;jeżeli nie to skok do
etykiety „nie_zero”
JZ rel
– ang. „Jump if Accumulator is Zero”, skocz
jeżeli w akumulatorze jest liczba 0 (zero)
– sprawdzana jest zawartość akumulatora (A),
jeżeli jest równa zero, to do licznika rozka−
zów PC dodawane jest przesunięcie „rel” –
na zasadach takich jak opisano wczesniej
przy okazji omawiania poprzednich instrukcji
skoków z argumentem „rel” (liczba 8–bito−
wa ze znakiem w kodzie U2).
PC <– PC + 2, jeśli A = 0, to PC <– PC + rel
– kod: 01100000
jest_zero:
;jeżeli tak to wykonuj po
zostałe instrukcje
.....
.....
nie_zero: ;tu nastapi skok jeżeli
rej.B był różny od zera
.....
;i zostaną wykonane te
instrukcje
60h
.....
A oto wspomniana wczesniej grupa instruk−
cji używana głównie w pętlach programo−
wych lub przy zwielokrotnionym sprawdza−
niu warunków zgodnosci określonych rejes−
trów z innym lub z argumentami stałymi.
Ogólna postać instrukcji jest następująca:
– cykle: 2
bajty: 2 (kod instrukcji 60h
+ przesunięcie „rel”)
– przykład:
MOV A, B
;załadowanie rej. B do
Acc celem sprawdzenia
czy = 0
.....
;pozostałe instrukcje
programu
.....
etyk01:
JZ
jest_zero ;jeżeli tak to skok do ety
kiety „jest_zero”
;właściwe miejsce skoku
według pozycji = 0
CJNE <arg1>, <arg2>, rel
nie_zero:
;jeżeli nie to wykonuj po
zostałe instrukcje
.....
;tu mozna umieścić
– ang. „Compare and Jump if Not Equal”, po−
równaj i skocz jeżeli argumenty porównania
nie są sobie równe
W instrukcji tej porównywane sa dwa argu−
menty: arg1 i arg2. Jeżeli nie są one równe
(ich wartości nie sa równe), to do zawartoś−
ci licznika rozkazów jest dodawane przesu−
nięcie „rel” na zasadach zgodnych z omó−
wionymi wczesniej. W efekcie zostaje wy−
konany skok w programie. Tu uwaga, skok
nastepuje względem instrukcji występują−
cej po instrukcji CJNE. Dodatkwo jest zmie−
niany znacznik przeniesienia C. I tak, jeżeli
w wyniku porównania okaże sie zę argum−
rent arg1 jest mniejszy od argumentu arg2
to do znacznika C wpisywana jest jedynka
(znacznik jest ustawiany), w przeciwnym
przypadku znacznik jest zerowany (C=0).
W zalezności od typu argumentów instruk−
cji możliwe są cztery przypadki, oto one.
– porównywany jest akumulator oraz komór−
ka wew. RAM o adresie podanym bezpo−
srednio jako argument „adres”
PC <– PC + 3, jesli A <> (adres), to PC <–
PC + rel
dodatkowo: C <– 0 gdy A>= (adres), lub
C<–1 gdy A< (adres)
– kod: 10110101 B5h
– cykle: 2 bajty: 3 (kod instrukcji
+ adres + przesunięcie „rel”)
– przykład:
MOV B,#56
check:
CJNE A, B, zwieksz
SJMP koniec
zwieksz:
INC A
SJMP check
koniec:
CLR B
......
W przykładzie tym do rejestru B wpisywana
jest liczba 56. Nastepnie sprawdzany jest
warunek zgodności akumulatora z rejest−
rem B, jeżeli nie są sobie równe, to akumu−
lator jest inkrementowany (dodawana jest
do niego jedynka) – patrz etykieta „zwiek−
sz”. Następnie operacja jest powtarzana od
początku – instrukcja „SJMP check”. Jeżeli
w końcu nastąpi zgodność obu rejestrów,
wykonywany jest skok do etykiety „ko−
niec”, gdzie rejestr B zostaje wyzerowany.
CJNE A, #dana, rel
– akumulator zostaje porównany z argumen−
tem bezpośrednim (8–bitową liczbą), jeżeli
nie są zgodne nastepuje skok.
PC <– PC + 3, jeśli A <> dana, to PC <–
PC + rel
dodatkowo: C <– 0 gdy A>= dana, lub C<–1
gdy A< dana
– kod: 10110100 B4h
– cykle: 2 bajty: 3 (kod instrukcji
+ dana + przesunięcie „rel”)
– przykład: niech w zmiennej (rejestrze) „kla−
wisz” będzie przechowywany kod wciśnę−
tego klawisza w systemie mikroprocesoro−
wym (ot choćby w naszym komputerku).
Jeżeli chcemy podjąć określone działanie
CJNE A, adres, rel
E LEKTRONIKA DLA WSZYSTKICH 1/98
45
1128248.001.png
Zgłoś jeśli naruszono regulamin