WOJSKOWA AKADEMIA TECHNICZNA
Architektura i organizacja komputerów II
Sprawozdanie z pracy laboratoryjnej
Nr 1
Student : Adrian Kępa
Grupa : I3X6S1
Nr : 14
Data : 14.03.2014r.
[1] Rozkazy przesłań
a) LB Load byte - rozkaz ten teoretycznie powinien przesłać jeden bajt
(8 bitów) z pamięci do podanego rejestru.
Kod programu:
.data
bajt_A: .byte 2
.text
lb r1, bajt_A
trap 0
Spodziewany wynik działania tego rozkazu to załadowanie bajtu "bajt_A" o
wartości 2 do rejestru r1. W tym wypadku rozkaz został wykonany poprawnie,
w rezultacie liczba 2 znalazła się w rejestrze r1.
Kod programu:
.data
bajt_A: .word 2
.text
lb r1, bajt_A
trap 0
W tym wypadku student przeoczył fakt, że zadeklarował "bajt_A" jako słowo a
próbuje wykonać rozkaz LB Load byte służący do wczytania bajtu, nie
słowa. W efekcie rejestr r1 pozostanie niezmieniony, rozkaz nie będzie
wykonany.
b) SW Store word - rozkaz ten teoretycznie powinien zapamiętać argument
będący słowem w drugiej zmiennej.
Kod programu:
.data
liczba_A: .word 50
liczba_B: .space 0
.text
lw r1, liczba_A
sw liczba_B, r1
lw r2, liczba_B
trap 0
Powyższy program działa zgodnie z przewidywaniami. Na początku, zostaje
wczytana wartość ze zmiennej "liczba_A" do rejestru r1. Potem przy użyciu
rozkazu SW, zawartość rejestru r1 zostaje zapamiętana w zmiennej "liczba_B".
Na koniec na potrzeby sprawdzenia, przesyłam zmienną "liczba_B" do rejestru
r2 w celu łatwego sprawdzenia działania programu. Rejestr r2 ma wartość 50,
czyli tyle ile wartość zmiennej "liczba_B". Dowodzi to tego, że rozkaz
przechowania słowa został poprawnie wykonany, słowo zostało zapamiętane w
zmiennej "liczba_B".
Kod programu:
.data
liczba_A: .word 50
liczba_B: .space 0
.text
lw r1, liczba_A
sw liczba_B, r1
lw r2, liczba_B
trap 0
[2] Rozkazy arytmetyczne i logiczne
a) ADDI
Add immediate w teorii, rozkaz ten do zawartości rejestru
będącego drugim argumentem, dodaje liczbę i zapisuje w innym rejestrze tą
sumę.
Kod programu:
.data
.text
addi r1, r0, #256
trap 0
Spodziewany przebieg działania tego rozkazu to dodanie liczby dziesiętnej 256
do zawartości rejestru r0 (zawsze 0) i zapisanie wyniku w rejestrze r1 czyli w
rejestrze r1 powinna znajdować się liczba 256. W tym wypadku praca programu
przebiega pomyślnie, do rejestru r1 zostaje przesłana liczba 256.
Kod programu:
.data
.text
addi r0, r1, #256
trap 0
Program nie zostanie wykonany zgodnie z przewidywaniem gdyż autor pomylił
kolejność dwóch pierwszych argumentów lub poprostu nie zdaje sobie sprawy z
tego, że nie da się zmienić wartości rejestru r0. Pierwszy argument rozkazu
ADDI jest miejscem do którego należy zapisać sumę - w tym przypadku
zawartości r1 + 256(dec) lecz suma ta nigdy nie znajdzie się w rejestrze r0.
Próba wykonania programu powoduje również pojawienie się ostrzeżenia
informującego nas o tym, iż rejest r0 został użyty jako miejsce zapisu sumy
zawartości rejestru r1 i 256.
b) AND Rozkaz obliczający iloczyn logiczny dwóch argumentów.
Kod programu:
.data
.text
addi r1, r0, #1
addi r2, r0, #0
and r3, r1, r2
trap 0
Na początku "sztucznie" wypełniono rejestry r1 i r2 nadając im początkowe
wartości 1 i 0. Program zadziałał zgodnie z przewidywaniami. Rozkaz AND
sprawdził czy obydwa argumenty zawartości rejestrów r1 i r2 mają wartość
logiczną "prawda". Tak nie jest, dlatego też zgodnie z działaniem rozkazu
iloczynu logicznego AND w rejestrze przeznaczonym na zapis wyniku r3,
znajdzie się 0.
Dla wartości rejestrów ze zbioru {0,1} rozkaz zachowuje się zgodnie z
przewidywaniami. Natomiast dla innych liczb, w rejestrze wynikowym nie
znajdzie się wartość logiczna 0 lub 1, tylko normalna liczba często różniąca się
od 0 i 1. Nie jestem pewien czemu taka sytuacja ma miejscę. Zdawało mi się, że
liczba w rejestrach > 0 zostanie potraktowana poprostu jako logiczna prawda.
[3] Rozkazy skoków
a) BEQZ Branch GPR equal to zero Rozkaz sprawdza, czy zawartość
rejestru podanego jako argument jest równa zero. Jeśli tak to wykonuje skok do
etykiety podanej jako drugi argument a w przeciwnym wypadku nic nie robi.
Pozwala to "omijać" wykonywanie pewnych partii kodu w sytuacjach gdy tego
potrzebujemy.
Kod programu:
.data
num_A: .word #5
num_B: .word #10
num_C: .word #0
.text
lw r1, num_A
lw r2, num_B
lw r3, num_C
beqz r3, objazd
add r4, r1, r2
objazd:
trap 0
Program zostanie wykonany zgodnie z przewidywaniami. Rozkaz beqz zostaje
wykonany pomyślnie, przyrównuje zawartość rejestru r3 do 0. Przyrównanie to
zwraca wartość logiczną więc wykonany zostaje skok do etykiety "objazd" co
powoduje z kolei pominięcie rozkazu dodawania ADD. Dla dodatkowego
sprawdzenia czy rzeczywiście rozkaz ADD nie został wykonany, sprawdzam,
że wartość rejestru r4 zostaje nadal równa zero.
W wypadku gdy słowo "num_C" jest różne od zera, zostaje pózniej wczytane
do rejestru r3, który to będzie warunkował wykonanie lub nie, rozkazu skoku
warunkowego. W przypadku różności od zera, wykonane zostanie dodawanie
add zawartości rejestrów r1 i r2. Zatem spodziewany wynik to liczba 15 w
rejestrze r4 i tak dzieje się w rzeczywistości.
b) Trap Wynikiem działania tego rozkazu jest przekazanie sterowania do
systemu.
Kod programu:
.data
.text
trap 0
Przewidujemy, że program zostanie wykonany i efektem będzie pomyślne
zakończenie. Tak też się dzieję, gdyż trap z argumentem 0 służy do zakończenia
programu.
Kod programu
.data
.text
trap 4
W tym przypadku student zapewne chciał wpisać trap 5 lub trap 3 lecz niestety
wpisał liczbę pomiędzy. Efektem tego będzie poprawna kompilacja programu,
lecz po uruchomieniu, nigdy się on nie zakończy(tzn, będzie działał tak długo
jak pozwolą na to zasoby komputera)
[4] Rozkazy zmiennoprzecinkowe
a) SUBF Subtract single precision float Zadaniem tego rozkazu jest
wykonanie różnicy na dwóch liczbach typu float i zapisanie wyniku w rejestrze.
(W tym przypadku wykorzystujemy rejestry dla liczb zmiennoprzecinkowych)
Kod programu:
.data
liczba_1: .float 8.30
liczba_2: .float 2.20
.text
lf f1, liczba_1
lf f2, liczba_2
subf f3, f1, f2
trap 0
Powyższy program działa zgodnie z przewidywaniami. Rozkaz SUBF zostaje
wykonany poprawnie, jego zadaniem jest odjęcie zawartości rejestru f2 od
zawartości rejestru f1. Wynikiem tego działania jest 6.1 i taka też liczba zostaje
przesłana do rejestru wynikowego f3.
Kod programu:
.data
liczba_1: .float 8.30
liczba_2: .float 2,20
.text
lf f1, liczba_1
lf f2, liczba_2
subf f3, f1, f2
trap 0
Powyższy przypadek ilustruje jak duże konsekwencje może mieć drobna
literówka. Student pomylił się i zamiast użyć kropki do oddzielenia części
całkowitej liczby od jej części ułamkowej, użył przecinka.
Efektem jest brak wyniku w rejestrze wynikowym f3, ponadto w rejestrze f2 do
którego została wczytana błędnie zadeklarowana wartość rejestru, wczytane
zostało tylko 2. Świadczy to o tym, że część ułamkowa po przecinku została w
tym przypadku pominięta.
b) GEF Greater or equal float Rozkaz ten porównuje wartości rejestrów
które podane są mu jako argumenty. Jeżeli pierwszy rejestr jest większy lub
równy od wartości drugiego rejestru to rejestr FPSR zostaje ustawiony na 1.
Kod programu:
.data
num_1: .float 9.0
num_2: .float 2.0
.text
lf f1, num_1
lf f2, num_2
gef f1, f2
trap 0
Program działa w sposób przewidywalny. Rozkaz porównania GEF ustawi
flagę FPSR na 1 gdyż zawartość rejestru f1 jest w tym przypadku większa od
wartości rejestru f2.
W przypadku gdyby pierwszy argument rozkazu GEF nie był większy lub
równy drugiemu argumentowi, rejestr FPSR pozostanie zerem.
Wnioski
Przy pisaniu programów do użytku w programie WinDLX należy zwracać
uwagę na specyficzną składnię języka. Należy nauczyć się, że do oddzielenia
części całkowitej od części ułamkowej liczb używamy kropki a nie przecinka.
Trzeba także zwracać uwagę na poprawną kolejność argumentów w rozkazach
oraz także wiedzieć czego się spodziewać po wykonaniu każdego rozkazu,
gdzie szukać wyników jego pracy.
Wyszukiwarka
Podobne podstrony:
L1 Introduction1L1 III Pol Normy okluzji hend out(1)L5 I3X6S1BST L1 teoria1 3 m2 L1MK1 S1 L1 przykładl1FiR matma L1LAB5 W Bąk EN DI2 L1L1ZP0784 ESOL L1 TN U2 Pr01L1 3 Reading06 l1 remonty i profilaktyka eksploatacyjna statkow powietrznychidc23niemiecki tha1 L1 einsendung Test1aMK1 S1 L1lakiernikq4[03] l1 04 ul1więcej podobnych podstron