Poprawa_sprawozdanie01_Brociek_Zemsta.pdf

(107 KB) Pobierz
Sprawozdanie nr 1
Brociek Adrian
Zemsta Paweł
Grupa 21A
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 być 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 - d yrektywa 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 – p owoduje, ż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 - o dję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
zakoń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.
1's
A 09
+ 3
256's 1's
256's
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
965469097.050.png 965469097.061.png 965469097.064.png 965469097.065.png 965469097.001.png 965469097.002.png 965469097.003.png 965469097.004.png
;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 ; zakończenie wykonywania programu
Po wykonaniu programu do koń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) .
965469097.005.png 965469097.006.png 965469097.007.png 965469097.008.png 965469097.009.png 965469097.010.png 965469097.011.png 965469097.012.png 965469097.013.png 965469097.014.png 965469097.015.png 965469097.016.png 965469097.017.png 965469097.018.png 965469097.019.png 965469097.020.png 965469097.021.png 965469097.022.png 965469097.023.png 965469097.024.png 965469097.025.png 965469097.026.png 965469097.027.png 965469097.028.png 965469097.029.png
 
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
965469097.030.png 965469097.031.png 965469097.032.png 965469097.033.png 965469097.034.png 965469097.035.png 965469097.036.png 965469097.037.png
;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
zmianą 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.
965469097.038.png 965469097.039.png 965469097.040.png 965469097.041.png 965469097.042.png 965469097.043.png 965469097.044.png 965469097.045.png 965469097.046.png 965469097.047.png 965469097.048.png 965469097.049.png 965469097.051.png 965469097.052.png 965469097.053.png 965469097.054.png 965469097.055.png 965469097.056.png 965469097.057.png 965469097.058.png 965469097.059.png 965469097.060.png 965469097.062.png 965469097.063.png
 
Zgłoś jeśli naruszono regulamin