Asembler

You might also like

You are on page 1of 47

Lista instrukcji

procesora 8051 część 2


Skoki i wywołania podprogramów,
operacje na stosie, operacje bitowe
Ryszard J. Barczyński, 2018
Politechnika Gdańska, Wydział FTiMS, Katedra Fizyki Ciała Stałego
Materiały dydaktyczne do użytku wewnętrznego
Przeniesienie sterowania
 Nasze dotychczasowe instrukcje wykonują się sekwencyjnie – jedna po
drugiej
 Programy, które rozwiązyją rzeczywiste problemy muszą mieć oczywiście
możliwość zmiany sekwencji wykonywanych instrukcji w zależności od
pewnych warunków
“If” akumulator jest równy 0 “then”

Odpal rakietę
“Else”
Poczekaj jeszcze chwilkę
 Osiąga się to przez instrukcje skoków i skoków warunkowych (czyli przez
przeniesienie sterowania oraz warunkowe przeniesienie sterowania)
Przeniesienie sterowania
 Mamy do wykonania następujące zadanie: A = R1+R0

Wylicz R1 + R0 i zachowaj w A
Umieść 0 w R2 R2 = 0

“If” A = 0 “then”
Umieść 13 w R2 FALSE
A == 0

Wylicz R2 + R3 i umieść wynik w


TRUE
R5
R2 = 13
 Bywykonać to zadanie potrzebujemy instrukcji
skoku warunkowego
JZ rel
R5 = R2 + R3
Przeniesienie sterowania:
JZ rel
 Instrukcja  Instrukcja ma długość 2
bajtów
JZ rel
 By zrozumieć jak działa ta
 Jeżeli A jest równe zero zmienia
instrukcja (i inne instrukcje
licznik programu (czyli adres
następnej instrukcji) o wartość skoków) przyjrzyjmy się
równą rel jeszcze adresowaniu
instrukcji w pamięci
 rel jest 8 bitową liczbą ze
programu.
znakiem
 możliwe jest przeniesienie
sterowania zarówno w
przód, jak i w tył
Adresowanie instrukcji

Rozważmy sekwencję W pamięci programu kod


poniższych instrukcji będzie miał następującą
postać:
MOV A,R0
ADD A,#55
MOV R5,A } MOV A,R0
E8
MOV R1,#26H 24
37 } ADD A,#55
Niektóre z instrukcji FD } MOV R5,A
maja rozmiar jednego
bajtu, niektóre dwóch.
79
26 } MOV R1,#26H
Adresowanie instrukcji

 Sekwencja działań procesora podczes wykonywania programu jest


następująca
 PC zawiera adres instrukcji, która ma być wykonana
 Następuje pobranie instrukcji i jej dekodowanie
 Opcode
 Operandy
 PC jest zwiększany o rozmiar instrukcji
 Ustalony w oparciu o opcode
 Instrukcja jest wykonywana

 Instrukcje skoku po prostu modyfikują rejestr PC


Przeniesienie sterowania:
JZ rel
Rozważmy instrukcję JZ rel w poniższym przykładzie

MOV A,R0 0000H E8 } MOV A,R0


ADD A,#55
0001H
0002H
24
37 } ADD A,#55
JZ 1 0003H
0004H
60
01
} JZ 01
MOV R5,A 0005H FD } MOV R5,A
MOV R1,#26H 0006H
0007H
79
26
} MOV R1,#26H

Po wykonaniu instrukcji JZ gdy A jest równy zero rejestr PC


będzie zawierał 0006H, a w przeciwnym wypadku 0005H
Przeniesienie sterowania:
JZ rel
W ogólności licznik programu (PC) zostanie zmodyfikowany
następująco
 If A is zero then
PC = PC + rel
Już przed wykonaniem instrukcji PC został zwiększony o 2
To jest rozmiar instrukcji JZ rel

Gdy A jest różne od zera, wtedy rel nie jest dodawany do PC i


zawiera on adres instrukcji następnej po JZ
Wartość rel może być pomiędzy –128 i +127
Skoki mogą być zatem wykonane w przód i w tył.
Przeniesienia sterowania:
JZ rel
Dobrawiadomość: zwykle nie Używamy etykiet
musimy liczyć adresów... Symbolicznych nazw adresów
Assembler zrobi to za nas! Assembler wyliczy
Zamiast przesunięcie
MOV A,R0
MOV A,R0 ADD A,#55
ADD A,#55 JZ fin
JZ 1 MOV R5,A
MOV R5,A fin: MOV R1,#26H
MOV R1,#26H
Uwaga: Większość assemblerów interpretuje
operand JZ jako adres, a nie adres względny!!!
Przeniesienie sterowania:
JNZ rel

Instrukcja

JNZ rel
Jestpodobna do JZ rel, ale skok jest
wykonywany wtedy, gdy zawartość
akumulatora jest różna od zera
A = R1+R0 Przykład: JNZ rel

R2 = 0

MOV A,R0
FALSE
A == 0 ADD A,R1
TRUE
MOV R2,#0
JNZ next
R2 = 13 MOV R2,#13
next: MOV A,R2
ADD A,R3

R5 = R2 + R3
Przeniesienie sterowania:
JC rel

Instrukcja

JC rel
Skok jest wykonywany wtedy, gdy
zawartość flagi przeniesienia C jest równa 1.
Przeniesienie sterowania:
JNC rel

Instrukcja

JNC rel
Skok jest wykonywany wtedy, gdy
zawartość flagi przeniesienia C jest równa 0.
Przeniesienie sterowania:
JB bit,rel

Instrukcja

JB bit,rel
Skok jest wykonywany wtedy, gdy
bezpośrednio adresowany bit bit jest
równy 1.
Przeniesienie sterowania:
JNB bit,rel

Instrukcja

JNB bit,rel
Skok jest wykonywany wtedy, gdy
bezpośrednio adresowany bit bit jest
równy 0.
Przeniesienie sterowania:
JBC bit, rel
Instrukcja

JBC bit,rel
Skok jest wykonywany wtedy, gdy
bezpośrednio adresowany bit bit jest
równy 1.
Bit jest następnie ustawiany na 0.
(niezależnie czy skok jest wykonywany)
Przykład
Sum = 0
Count = 10

Policzyć
sumę liczb od 1 do 10 Sum = Sum +
Count

Rozwiązanie
Rysunek pokazuje pętlę Reduce Count by
1
Użyjemy rejestrów 8051
R2 do obliczenia sumy
FALSE
R1 jako licznik Is Count equal to 0

TRUE
Przykład

R2=0 MOV R2,#0


R1 = 10 MOV R1,#10

loop :MOV A,R2


R2 = R2 + R1 ADD A,R1
MOV R2,A

MOV A,R1
CLR C
Reduce R1 by 1 SUBB A,#1
MOV A,R1

FALSE FALSE
R1 == 0 JNZ loop

TRUE TRUE
Przykład (z DEC)
MOV R2,#0
MOV R1,#10 MOV R2,#0
Loop: MOV A,R2 MOV R1,#10
ADD A,R1 Loop: MOV A,R2
MOV R2,A ADD A,R1
MOV A,R1 MOV R2,A
CLR C DEC R1
SUBB A,#1 MOV A,R1
MOV R1,A JNZ Loop
JNZ Loop
Przeniesienie sterowania:
CJNE A,#data,rel
Nazwa instrukcji:
Compare & Jump if Not Equal (CJNE)
Elastyczniejsza niż JZ i JNZ, ale 3 ma bajty długości
Działanie:
Porównanie zawartości A ze stałą #data i gdy te
wielkości nie są równe rel jest dodawane do licznika
programu (PC).
Modyfikuje flagę C gdy (A) < #data.
Instrukcja CJNE
Możliwości:

CJNE A,#data,rel Której użyć? Zależy


CJNE A,direct,rel
CJNE Rn,#data,rel co porównujesz...
CJNE @Ri,#data,rel
Wszystkie powyższe instrukcje porównują dwie
wielkości i wykonują skok, gdy nie są one równe (oraz
ustawiają odpowiednio wskaźnik C)
> rejestr A ze stałą
> rejestr A z zawartością komórki pamięci
> rejestr Rn ze stałą
> zawartość komórki pamięci adresowanej pośrednio ze stałą
Przykład: CJNE
W zależności od R4 wykonaj różne fragmenty kodu
Test: CJNE R4,#0H,Less
… ; R4 równy zero
JMP Endtest
Less: MOV A,R4
ANL A,#80H
CJNE A,#80H,Greater
… ; Mniej niż zero
JMP Endtest
Greater: … ; Większy od zera

Endtest:
Przeniesienie sterowania:
DJNZ Rn,rel
Następna uniwersalna i złożona instrukcja skoku:
Decrement & Jump if Not Zero (DJNZ)
Używana do wykonywania pętli z licznikiem
Zawartość rejestru Rn jest zmniejszana o 1, a
następnie jezeli wynik jest różny od zera licznik
programu (PC) jest modyfikowany – zostaje do
niego dodana wartość rel (czyli zostaje
wykonany skok).
Instrukcja DJNZ
Możliwe formaty
DJNZ Rn,rel
DJNZ direct,rel
Wskaźniki nie są modyfikowane
Obie instrukcje zmniejszają zawartość pierwszego
operandu i wykonują skok jeżeli się wyzerował.
> Pierwsza instrukcja dekrementuje i testuje Rn
» rozmiar 2 bajtów
> Druga instrukcja (mocna !) dekrementuje i testuje bezpośrednio
adresowaną komórkę pamięci
» rozmiar 3 bajtów
Przykład (z DJNZ)

MOV R2,#0
CLR A
MOV R1,#10
MOV R1,#10
Loop: MOV A,R2
Loop: ADD A,R1
ADD A,R1
DJNZ R1,Loop
MOV R2,A
MOV R2,A
MOV A,R1
CLR C
SUBB A,#1
MOV R1,A
JNZ Loop
Instrukcje skoków
Potrzebujemy
również instrukcji skoków
bezwarunkowych
Ładują
one adres do rejestru PC
Odpowiadają instrukcji goto języków wyższego poziomu

Nie ma ograniczeń odnośnie adresu docelowego


Ostrożnie...

Używane w wielu wypadkach, na przykład


Często twotzą główną pętlę programu
W konstrukcji If-Else
W instrukcji wyboru
Wyskoki z pętli
Instrukcje skoków
Istnieją 3 instrukcje skoków
SJMP rel Przykład:
AJMP addr11 JZ elseif
LJMP addr16 ADD A,R1
Pierwszato krótki skok MOV R2,#0
względny (SJMP) SJMP endif
Do PC jest dodawana 8 bitowa elseif: MOV R2,#13
wartość ze znakiem (rel).
skacze do 128 bajtów w tył i endif: MOV A,R2
127 bajtów w przód ADD A,R3
ma rozmiar 2 bajtów
Instrukcje skoku
Druga instrukcja skoku to Potencjalnie możliwy jest
skok absolutny (AJMP) z skok dalszy (2047 bajtów)
użyciem adresu 11 bitowego niż za pomocą SJMP.
Niższe 11 bitów PC jest Dokładniej dostępne są
zamieniane przez 11 bitów wszystkie adresy, które leżą
określonych w instrukcji wewnątrz 2K bloku, aktualnie
Rozmiar - również 2 bajty
adresowanego przez PC

PC a a a a a a a a a a a

PC bits unchanged by PC bits modified by


instruction instruction
Instrukcje skoku
Trzecia instrukcja skoku to długi skok absolutny
(LJMP) z użyciem 16 bitowego adresu.
16 bitów rejestru PC jest zamieniane przez 16 bitów
adresu wyspecyfikowanych w instrukcji.
Skok może być wykonany do dowolnej pozycji w 64K
pamięci programu.
Rozmiar instrukcji to 3 bajty

PC a a a a a a a a a a a a a a a a

All PC bits modified by instruction


Instrukcje skoku
Przykład:
OK, są 3 instrukcje skoku.
Której użyć??? JZ elseif
Odpowiedź: Pozwól ADD A,R1
zadecydować assemblerowi... MOV R2,#0
Użyj “instrukcji” JMP
Assembler
JMP endif
wybierze tą
właściwą elseif: MOV R2,#13
... i zamieni JMP na jedną z
endif: MOV A,R2
3 instrukcji.
ADD A,R3
e_count = 0
o_count = 0

s = start address
of string Przykład
FALSE
is value at s
not equal to 0

TRUE
Policz wystąpienia
liter 'e' i 'o' w
is value at s
TRUE
equal to 'e'
FALSE
łańcuchu
Increment is value at s
umieszczonym od
e_count
TRUE
equal to 'o'
FALSE
adresu 20h i
Increment zakończonym 00h.
o_count
Wyniki umieść w
R1 oraz R2
Increment s
Przykład: rozwiązanie
e_count = 0
o_count = 0

s = start address
of string MOV R1,#0
MOV R2,#0
FALSE
is value at s
not equal to 0
MOV R0,#20H
Loop: MOV A,@R0
TRUE

JZ Loopend
is value at s
equal to 'e'
TRUE FALSE

Increment
e_count
TRUE
is value at s
equal to 'o'
FALSE
CJNE @R0,#’e’,Testo
INC R1
Increment
o_count
JMP Fintest
Testo: CJNE @R0,#’o’,Fintest
Increment s
INC R2
Fintest: INC R0
JMP Loop
Pisanie w assemblerze Loopend:
raczej nie jest trywialne!
Skok pośredni
Specjalna wersja instrukcji skoku

JMP @A+DPTR
z użyciem 16 bitowego adresu, będącego sumą
zawartości DPTR i akumulatora.
umożliwia skoki wyliczane według tabeli
skoków.
Wywołanie podprogramów
Istnieją
2 instrukcje wywołania Przykład:
podprogramów ADD A,R1
ACALL addr11 ACALL proc
LCALL addr16 MOV R2,#0
Powrót z podprogramu .....
(procedury, funkcji) następuje po
wykonaniu instrukcji
proc: MOV R2,#13
MOV A,R2
RET
RET
Wywołanie podprogramu
Pierwsza (ACALL) instrukcja to Położenie startu
wywołanie podprogramu z podprogramu – w bloku 2047
użyciem adresu 11 bitowego bajtów.
(PC) <- (PC) + 2
PC czyli adres powrotu
(SP) <- (SP) + 1
(adres następnej instrukcji do
((SP)) <- (PC7..0) wykonania po zakończeniu
(SP) <- (SP) + 1 podprogramu) jest
((SP)) <- (PC15..8) zachowywany na stosie.
(PC10..0) <- addr11 Inne rejestry nie są
Rozmiar - 2 bajty zachowywane.
Wywołanie podprogramu
Druga (LCALL) instrukcja to Położenie startu
wywołanie podprogramu z podprogramu – w bloku 2047
użyciem adresu 16 bitowego bajtów.
(PC) <- (PC) + 2
PC czyli adres powrotu
(SP) <- (SP) + 1
(adres następnej instrukcji do
((SP)) <- (PC7..0) wykonania po zakończeniu
(SP) <- (SP) + 1 podprogramu) jest
((SP)) <- (PC15..8) zachowywany na stosie.
(PC15..0) <- addr16 Inne rejestry nie są
Rozmiar - 3 bajty zachowywane.
Wywołanie podprogramu
OK, są 2 instrukcje Przykład:
wywołania podprogramu.
Której użyć??? MOV A,#10
Odpowiedź: Pozwól CALL proc
zadecydować MOV R2,#0
assemblerowi... ......
Użyj “instrukcji” CALL
Assembler wybierze tą
właściwą proc: MOV R2,#13
... i zamieni CALL na
jedną z 2 instrukcji.
ADD A,R2
RET
Powrót z podprogramu
Instrukcja powrotu (RET)
ładuje do licznika programu Instrukcja znajduje
(PC) adres powrotu zastosowanie do powrotów z
zachowany na stosie podprogramów wywołanych
(PC15..8) <- ((SP)) zarówno długą, jak i któtką
(SP) <- (SP) - 1 instrukcją CALL.
(PC7..0) <- ((SP))
(SP) <- (SP) - 1
Operacje na stosie: PUSH
Umieść na stosie zawartość komórki pamięci

PUSH direct
do rejestrów SFR można się odwoływać poprzez
ich adresy w obszarze SFR (na przykład ACC)
adresowanie przez SP jest pośrednie – dotyczy do
256 bajtów wewnętrznej pamięci RAM
(SP) <- (SP) + 1
((SP)) <- direct
Operacje na stosie: POP
Pobierz ze stosu zawartość komórki pamięci

POP direct
do rejestrów SFR można się odwoływać poprzez
ich adresy w obszarze SFR (na przykład ACC)
adresowanie przez SP jest pośrednie – dotyczy do
256 bajtów wewnętrznej pamięci RAM
(direct) <- ((SP))
(SP) <- (SP) - 1
Operacje na bitach

Procesor 8051 posiada kilka instrukcji


umożliwiających manipulację pojedynczymi bitami
Rolę “akumulatora 1-bitowego” pełni wskaźnik C w
rejestrze PSW
Inne poza nim wskaźniki nie są zmieniane przez te
instrukcje, chyba że instrukcja ich explicite dotyczy
Operacje na bitach: CLR
Instrukcje zerowania

CLR C
CLR bit

Instrukcjazeruje flagę C
lub bezpośrednio adresowany bit w obszarze
pamięci RAM adresowalnym bitowo.
Operacje na bitach: SETB
Instrukcje ustawiania jedynki

SETB C
SETB bit

Instrukcjaustawia jedynkę na wskaźniku C


lub bezpośrednio adresowany bit w obszarze
pamięci RAM adresowalnym bitowo.
Operacje na bitach: CPL
Logiczna negacja

CPL C
CPL bit

Instrukcjaneguje wskaźnik C
lub bezpośrednio adresowany bit w obszarze
pamięci RAM adresowalnym bitowo.
Operacje na bitach: ANL
Logiczny iloczyn

ANL C,bit
ANL C,/bit

 Instrukcjaliczy logiczny iloczyn C i bezpośrednio


adresowanego bitu
 lub logiczny iloczyn C i negacji bezpośrednio adresowanego
bitu
 wynik jest umieszczany w C.
Operacje na bitach: ORL
Logiczna suma

ORL C,bit
ORL C,/bit

 Instrukcja liczy logiczną sumę C i bezpośrednio adresowanego


bitu
 lub logiczną sumę C i negacji bezpośrednio adresowanego bitu
 wynik jest umieszczany w C.
Nie rób nic: NOP
Instrukcja

NOP

Niewykonuje żadnych czynności oprócz zajmowania


pamięci programu i zangażowania czasu procesora.

You might also like