Sprawozdanie nr 1
Symulacja dzia
łania 8051 - arytmetyka 16-to bitowa:
ADD (dodawanie), SUBB(odejmowanie)
Opis:
Akumulator - jest rejestrem roboczym, najbardziej uniwersalnym poniewa
ż może być
argumentem wielu rozkaz
ów, w których użycie innego rejestru nie jest możliwe. Nie
powinien b
yć on używany do przechowywania danych w dłuższych sekwencjach programu,
gdy prawdopodobnie b
ędzie potrzebny do bieżących operacji w kolejnych rozkazach.
EQU - dyrektywa EQU przypisuje wyra
żenie numeryczne lub symbol rejestru do specyfikowanej
nazwy symbolu.
DATA - dyrektywa DATA przydziela do specyfikowanej nazwy obszar wewn
ętrznej pamięci RAM.
Wyra
żenie numeryczne musi być z zakresu 0 do 255. Symbol definiowany dyrektywą nie może być
powt
órnie użyty w programie.
PROG SEGMENT CODE - Definiuje segment o nazwie PROG w klasie pami
ęci CODE, czyli w
pami
ęci programu. Wszystko co pojawi się w tym segmencie będzie umieszczone w jego pamięci .
Po zdefiniowaniu nazwy segmentu nale
ży go wybrać, używając dyrektywy RSEG.
CSEG AT nr
– powoduje, że napisany niżej kod ma być umieszczony w pamięci programu
pocz
ąwszy od podanego adresu „nr” .
RSEG nazwa - rozpoczyna segment zdefiniowany przy pomocy PROG SEGMENT CODE (w
przypadku naszego programu ma on nazw
ę PROG). Od tego momentu, znajdujący się poniżej
kod zostanie umieszczony w pami
ęci programu. Raz rozpoczęty segment jest
wa
żny do czasu rozpoczęcia nowego.
JMP nazwa
– powoduje przemieszczenie się (skok) do miejsca oznaczonego jako „nazwa”.
ADD A,dana
– dodaje wartość z komórki o adresie zastąpionym tekstem „dana” do Akumulatora,
bez przeniesienia.
ADDC A,dana
– dodaje wartość z komórki o adresie zastąpionym tekstem „dana” do
Akumulatora, z uwzgl
ędnieniem przeniesienia.
MOV gdzie,sk
ąd – kopiuje wartość z komórki o adresie zastąpionym tekstem „skąd” do komórki o
adresie zast
ąpionym tekstem „gdzie”.
SUBB A,dana - odj
ęcie od wartości zapisanej w Akumulatorze wartość komórki pamięci „dana”
Je
żeli dana>A to nastąpi pożyczka „1” z zewnątrz, co zostanie zasygnalizowane zmianą flagi cy na
„1”. Jeżeli flaga cy była ustawiona na „1”, to odejmowana jest także pożyczka wykonana przez
poprzednie wywo
łanie odejmowania (jeżeli takowe nastąpiło).
CLR C
– wyzerowanie przeniesienia (będzie to najmłodszy bit wyniku) .
END - dyrektywa musi by
ć umieszczona w ostatniej linii programu źródłowego, jest warunkiem
zak
ończenia programu.
Dodawanie dw
óch liczb 16-bitowych:
Rozkaz dodawania, kt
órego pierwszym argumentem jest zawsze akumulator (w nim pozostaje
r
ównie wynik dodawania) jest dostępny w dwóch wariantach:
ADD - dodawanie bez przeniesienia
ADDC - dodawanie z przeniesieniem (flaga CY)
Najwi
ększa wartość, która może zmieścić się w 16-bitach to 256*256-1 czyli 65 535. Dodając do
siebie 65 535 i 65 535 otrzymamy 131 070
– ta wartość mieści się w 17-bitach. Czyli dodawanie
16-bitowe dw
óch wartości 16-bitowych daję w wyniku wartość co najwyżej 17-bitową.
Dla przyk
ładu rozważmy dodawanie liczb 2569 i 1000 co da wynik 3569. Najpierw przekształćmy
wyra
żenie na system szesnastkowy: A09h x 3E8h.
's
's
A
09
+
3
E8
=
D
F1
Najpierw dodajemy liczby z kolumny 1's (m
łodsze bajty): 09 + E8 = F1. W pierwszej kolumnie
mo
że zmieścić się tylko 2-cyfrowa wartość szesnastkowa. Więc jeżeli mamy jakiś nadmiar to
musimy pami
ętać aby przenieść go do kolumny ze starszymi bajtami. Dodajemy teraz starsze bajty:
A+3=D. Musimy pami
ętać o przeniesieniu nadmiaru z kolumny 1's. W naszym przypadku takowego
nie by
ło, więc wartość wyniku nie ulegnie zmianie. Tak więc ostateczny wynik to DF1, co da 3569
w kodzie dziesi
ętnym.
Proces wykonywany w asemblerze b
ędzie identyczny.
65536's
256's
1's
R6
R7
+
R4
R5
=
R1
R2
R3
Nasza pierwsza liczba zostanie zawarta w R6 oraz R7, natomiast druga w R4 i R5. Wynik
dodawanie trafi do R1,R2 i R3. Nasz program b
ędzie się składał z trzech następujących kroków:
1. Dodanie m
łodszych bajtów R7 i R5 – pozostawienie wyniku w R3.
2. Dodanie starszych bajt
ów z R6 i R4, z uwzględnieniem przeniesienia – pozostawienie
wyniku w R2.
3. Umieszczenie przeniesienia z kroku 2, w ostatnim bajdzie R1.
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pami
ęci CODE
Stala EQU 1000 ;1000(dec)=3E8(hex) . W celu odwo
łania się do interesującej nas części
sta
łej używać będziemy operatora HIGH (starszy bajt) lub LOW (młodszy bajt)
DanaL DATA 20h ;przechowuje m
łodszy bajt wprowadzanej liczby
DanaH DATA 21h ;przechowuje starszy bajt wprowadzanej liczby
WynikL DATA 30h ;przechowuje m
łodszy bajt wyniku
WynikH DATA 31h ;przechowuje starszy bajt wyniku
CSEG AT 0 ;kod programu b
ędzie umieszczony w jego pamięci począwszy od adresu „0”
JMP start ;skok do miejsca oznaczonego etykiet
ą start
RSEG PROG ;rozpoczyna segment, od kt
órego, znajdujący się poniżej kod zostanie
umieszczony w pami
ęci programu
;W oknie pami
ęci „Memory 1” zapisujemy nasze dane. Do komórki o adresie D:0x20 wpisujemy
m
łodszy bajt pierwszej liczby, a tuż obok pod adres D:0x21 starszy bajt danej liczby.
start:
MOV A,DanaL ;skopiowanie warto
ści z komórki o adresie zastąpionym tekstem DanaL do
akumulatora A. W zak
ładce „Sys” widzimy właśnie tę zmianę – wartość a=0x09.
ADD A,#low(Stala) ;dodaje do Akumulatora m
łodszy bajt ze stałej Stala. W zakładce
„Sys” widzimy zmianę wartości a na 0xf1.
MOV WynikL,A ;skopiowanie warto
ści z akumulatora A do komórki o adresie
zast
ąpionym tekstem WynikL. Komórka o adresie 0x30h przyjęła wartość F1.
MOV A,DanaH ;skopiowanie warto
ści z komórki o adresie zastąpionym tekstem DanaH do
akumulatora A. W zak
ładce „Sys” widzimy właśnie tę zmianę – wartość a=0x0a.
ADDC A,#high(Stala) ;dodaje do Akumulatora starszy bajt ze sta
łej Stala. W zakładce
„Sys” widzimy zmianę wartości a na 0x0d, z uwzględnieniem przeniesienia – czyli
dodaniem warto
ści z flagi cy – w naszym przypadku zera.
MOV WynikH,A ;kopiowanie warto
ści z akumulatora A do komórki o adresie
zast
ąpionym tekstem WynikH. Komórka o adresie 0x31h przyjęła wartość 0D.
END ;zak
ończenie wykonywania programu
Po wykonaniu programu do k
ońca, w komórkach o adresach od D:0x30 i D:0x31 zawarty
zostanie wynik z dodawania.
Odejmowanie dw
óch liczb 16-bitowych:
Rozkaz odejmowania SUBB (odjemna zawsze w akumulatorze, tam r
ównie wynik) jest
wykonywany zawsze z po
życzką której funkcję pełni flaga CY. Przy prostym odejmowaniu
warto
ści jednobajtowych należy pamiętać o zmianie wartości flagi cy na „0” (wyzerowanie) .
16-bitowe odejmowane dw
óch wartości 16-bitowych da w wyniku maksymalnie liczbę 16-bitową.
Na przyk
ład od 65535 odejmijmy 1 – otrzymamy wartość 16-bitową.
Dla przyk
ładu rozważmy odejmowanie następujących dwóch wartości dziesiętnych: 5518 – 3219 =
2299. Najpierw przekszta
łćmy wartości na kod szesnastkowy – 158E - C93.
256's
1's
15
8E
-
C
93
=
8
FB
Najpierw odejmujemy liczby z kolumny 1's (m
łodsze bajty): 8E – 93. Liczba 93 jest większa niż 8E,
dlatego musimy
„pożyczyć” z kolumny 256's jedynkę. Tak więc wykonamy odejmowanie 18E-93 =
FB. Teraz wykonujemy odejmowanie 15-C. Musimy jednak pami
ętać, że „pożyczyliśmy” jedynkę z
tej kolumny. Tak wi
ęc mamy 15-C-1=8. Stąd nasza ostateczna odpowiedź to 8FB, czyli 2299 w
kodzie dziesi
ętnym.
Proces wykonywany w asemblerze b
ędzie identyczny.
256's
1's
R6
R7
-
R4
R5
=
R2
R3
Nasza pierwsza liczba zostanie zawarta w R6 oraz R7, natomiast druga w R4 i R5. Wynik
odejmowania trafi do R2 i R3. Nasz program b
ędzie się składał z dwóch następujących kroków:
1. Odj
ęcie młodszych bajtów R5 od R7, pozostawienie wyniku w R3.
2. Odj
ęcie starszych bajtów R4 od R6, uwzględnienie „pożyczki”, pozostawienie wyniku w
R2.
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pami
ęci CODE
L1L DATA 20h ;przechowuje m
łodszy bajt wprowadzanej liczby - odjemnej
L1H DATA 21h ;przechowuje starszy bajt wprowadzanej liczby - odjemnej
L2L DATA 22h ;przechowuje m
łodszy bajt wprowadzanej liczby - odjemnik
L2H DATA 23h ;przechowuje starszy bajt wprowadzanej liczby - odjemnik
WL DATA 30h ;przechowuje m
łodszy bajt wyniku
WH DATA 31h ;przechowuje starszy bajt wyniku
CSEG AT 0 ;kod programu b
ędzie umieszczony w jego pamięci począwszy od adresu „0”
JMP start2 ;skok do miejsca oznaczonego etykiet
ą start 2
RSEG PROG ;rozpoczyna segment, od kt
órego, znajdujący się poniżej kod zostanie
umieszczony w pami
ęci programu
;W oknie pami
ęci „Memory 1” zapisujemy nasze dane. Do komórki o adresie D:0x20 wpisujemy
m
łodszy bajt pierwszej liczby, a tuż obok pod adres D:0x21 starszy bajt danej liczby. Kolejną
liczb
ę zapisujemy pod adresem D:0x22 – młodszy bajt i D:0x23 – starszy bajt.
start2:
MOV A,L1L ;skopiowanie warto
ści z komórki o adresie zastąpionym tekstem L1L do
akumulatora A. W zak
ładce „Sys” widzimy właśnie tę zmianę – wartość a=0x8e. CLR
C ;ustawienie warto
ści flagi cy na „0” - wyzerowanie pożyczki
SUBB A,L2L ;odj
ęcie od wartości zapisanej w Akumulatorze wartość z komórki pamięci
L2L . Je
żeli L2L>A to nastąpi pożyczka „1” z zewnątrz, co zostanie zasygnalizowane
zmi
aną flagi cy na „1”. Wartość akumulatora A będzie równa 0xfb.
MOV WL,A ;kopiowanie warto
ści z akumulatora A do komórki o adresie zastąpionym
tekstem WL. Kom
órka o adresie0x30h przyjęła wartość FB.
MOV A,L1H ;skopiowanie warto
ści z komórki o adresie zastąpionym tekstem L1H do
akumulatora A. W zak
ładce „Sys” widzimy właśnie tę zmianę – wartość a=0x15. SUBB
A,L2H ;odj
ęcie od wartości zapisanej w Akumulatorze wartość komórki pamięci
L2H. Je
żeli flaga cy jest ustawiona na „1”, to odejmowana jest także pożyczka wykonana
przez poprzednie wywo
łanie odejmowania. Nastąpi wyzerowanie flagi cy. Wartość
akumulatora A b
ędzie równa 0x08.
MOV WH,A ;kopiowanie warto
ści z akumulatora A do komórki o adresie zastąpionym tekstem
WH. Kom
órka o adresie 0x30h przyjęła wartość 08.
END ;zak
ończenie wykonywania programu
Po wykonaniu programu do k
ońca, w komórkach o adresach od D:0x30 i D:0x31 zawarty
zostanie wynik odejmowania.
Podczas pisania sprawozdania korzysta
łem z następujących pomocy:
http://www.8052.com/add16
http://www.8052.com/subb16
http://staff.iiar.pwr.wroc.pl/antoni.sterna/lab_51/programowanie_51.pdf