Sprawozdanie nr 5
8051 - operacje na stosie
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.
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.
CSEGAT 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”.
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”.
CLR – wyzerowanie.
END - dyrektywa musi być umieszczona w ostatniej linii programu źródłowego, jest warunkiem zakończenia programu.
SJMP a- przejście do etykiety o nazwie a
Program cw3p1
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
CSEGAT 0 ;kod programu będzie umieszczony w jego pamięci począwszy od adresu „0” JMP reset ;skok do miejsca oznaczonego etykietą reset
RSEG PROG ;rozpoczyna segment, od którego, znajdujący się poniżej kod zostanie umieszczony w pamięci programu
reset:
MOV A,#'G' ;przypisanie do akumulatora A kodu litery G . Widzimy, że akumulator zmienił swoją wartość na 0x47.
PUSH ACC ;odłożenie zawartości akumulatora A na stos . Rejestr wskaźnika stosu zwiększył się o jeden. W oknie pamięci widzimy, że pod adres 0x08 została wpisana wartość z akumulatora – 47.
MOV A,#'U' ;przypisanie do akumulatora A kodu litery U. Widzimy, że akumulator zmienił swoją wartość na 0x55.
PUSH ACC ;odłożenie zawartości akumulatora A na stos . Rejestr wskaźnika stosu ponownie zwiększył się o jeden. W oknie pamięci widzimy, że pod adres 0x09 została wpisana wartość z akumulatora – 55.
CLR A;wyczyszczenie akumulatora. Widzimy, że akumulator zmienił swoją wartość na
0x00.
POP ACC ;pobieranie wartości ze stosu do akumulatora A . Nastąpiło zmniejszenie rejestru wskaźnika stosu SP o jeden. Zaś akumulator przyjął wartość 0x55.
MOV 30h,A ;przypisanie pod adres 30h wartości z akumulatora A. W oknie pamięci widzimy, że pod adres 0x30 została wpisana wartość 55.
POP ACC ;pobieranie wartości ze stosu do akumulatora A . Nastąpiło ponowne zmniejszenie rejestru wskaźnika stosu SP o jeden. Zaś akumulator przyjął wartość 0x47. MOV 31h,A ;przypisanie pod adres 31h wartości z akumulatora A. W oknie pamięci widzimy, że pod adres 0x30 została wpisana wartość 47.
SJMP $ ;pozostań tutaj (pętla nieskończona) END ;zakończenie wykonywania programu
Jeżeli ustawimy początkowy adres stosu na 0x3Fh to dane z powyższego programu zostaną przechowane na stosie pod adresami 0x40h i 0x41h.
Program cw3p2
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
CSEGAT 0 ;kod programu będzie umieszczony w jego pamięci począwszy od adresu „0” JMP reset ;skok do miejsca oznaczonego etykietą reset
RSEG PROG ;rozpoczyna segment, od którego, znajdujący się poniżej kod zostanie umieszczony w pamięci programu
reset:
MOV B,#'G' ;przypisanie do rejestru B kodu litery G . Widzimy, że arejestr B zmienił swoją wartość na 0x47.
PUSH B ;odłożenie zawartości rejestru B na stos . Rejestr wskaźnika stosu zwiększył się o je den. W oknie pamięci widzimy, że pod adres 0x08 została wpisana wartość z rejestry B – 47. POPACC ;pobieranie wartości ze stosu do akumulatora A . Nastąpiło zmniejszenie rejestru wskaźnika stosu SP o jeden. Zaś akumulator przyjął wartość 0x47.
MOV 30h,A ;przypisanie pod adres 30h wartości z akumulatora A. W oknie pamięci widzimy, że pod adres 0x30 została wpisana wartość 47.
SJMP $ ;pozostań tutaj (pętla nieskończona) . END ;zakończenie wykonywania programu.
Instrukcja PUSH spowodowała zwiększenie rejestru wskaźnika stosu SP o jeden oraz przeniesienie wartości z rejestru B na stos. Z kolei instrukcja POP zmniejszyła rejestr wskaźnika stosu SP o jeden – jego stan powrócił do początkowego. Zaś wartość ze stosu została przypisana do akumulatoraA.
Program cw3p3
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
CSEGAT 0 ;kod programu będzie umieszczony w jego pamięci począwszy od adresu „0” JMP reset ;skok do miejsca oznaczonego etykietą reset
RSEG PROG ;rozpoczyna segment, od którego, znajdujący się poniżej kod zostanie umieszczony w pamięci programu
reset:
MOV DPTR,#outdata ;przypisanie pod DPTR wartości z outdata. Widzimy, że zmienna DPTR przyjęła wartość 0x081c.
CLRA;wyczyszczenie akumulatora. Widzimy, że akumulator zmienił swoją wartość na 0x00. loop:
PUSH ACC ;odłożenie zawartości akumulatora A na stos . Rejestr wskaźnika stosu SP zwięk szył się o jeden.
MOVC A,@A+DPTR ;przenosi bajt kodu. Nie naruszając flagi. Przenosi bajt danych znajdują cych się w pamięci ROM kodu programu do akumulatora A. Akumulator A przyjął wartość E7h, zaś zmienna DPTR – 0x0807h.
ACALL delay ;nastąpiło zwiększenie rejestru wskaźnika stosu SP o jeden. Przeskok do etykiety delay.
MOV P2,A ;przypisanie pod port drugi wartości z akumulatora A.
POPACC ;pobieranie wartości ze stosu do akumulatora A . Nastąpiło zmniejszenie rejestru wskaźnika stosu SP o jeden.
INC A;inkrementacja akumulatora.
ANLA,#03h ;bity odpowiadające 0 w liczbie 03h są zerowane, pozostałe bez zmian. AJMP loop
delay:
PUSH ACC ;odłożenie zawartości akumulatora A na stos . Rejestr wskaźnika stosu ponownie zwiększył się o jeden.
MOVA,#255 ;przypisanie pod akumulator A wartości 255.
DJNZ ACC,$ ;dekrementacja akumulatora i skok, jeśli po dekrementacji wartość niezerowa. POPACC ;pobieranie wartości ze stosu do akumulatora A . Nastąpiło zmniejszenie rejestru wskaźnika stosu SP o jeden.
RET
outdata: DB DB DB
DB
11100111b 11000011b 10000001b
00000000b
END ;zakończenie wykonywania programu
Własny program:
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
j DATA 20h ;przechowuje wartość jednostek. d DATA 21h ;przechowuje wartość dziesiątek. s DATA 30h ;przechowuje wartość setek.
t DATA 31h ;przechowuje wartość tysięcy.
t1 DATA 27h ;przechowuje wartość zmiennej t1. t2 DATA 26h ;przechowuje wartość zmiennej t2. t3 DATA 25h ;przechowuje wartość zmiennej t3. t4 DATA 24h ;przechowuje wartość zmiennej t4.
CSEGAT 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
start:
MOV j,#0x0 ;wyzerowanie zmiennej j. MOV d,#0x0 ;wyzerowanie zmiennej d. MOV s,#0x0 ;wyzerowanie zmiennej s. MOV t,#0x0 ;wyzerowanie zmiennej t.
MOV t1,#0xFF ;przypisanie pod zmienną t1 wartości FFh. Widzimy, że w oknie pamięci komórka o adresie 0x27 przyjęła wartość FF.
JMP start2 ;przeskok do etykiety start2.
start2:
MOV t1,j ;przypisanie pod zmienną t1 wartości ze zmiennej j. INC j ;inkrementacja zmiennej j.
MOV A,#0xA ;przypisanie pod akumulator A wartości Ah. SUBB A,j ;odjęcie wartości jedności j od akumulator A.
JNZ start2 ;skok do etykiety start2 jeśli nie wszystkie zadane bity są ustawione. MOV j, #0x0 ;przypisanie pod zmienną j wartości 0h.
MOV t1,j ;przypisanie pod zmienną t1 wartości ze zmiennej j. ;Odjęcie młodszego bajtu od aku mulatora A.
JMP start3 ;przeskok do etykiety start3.
start3:
MOV A,#0x9 ;przypisanie pod akumulator A wartości 9h. SUBB A,d ;odjęcie wartości dziesiątek d od akumulator A.
JZ start4 ;skok do etykiety start4 jeśli wszystkie zadane bity są zerowe INC d ;inkrementacja zmiennej d.
MOV t2,d ;przypisanie pod zmienną t2 wartości ze zmiennej d. JMP start2 ;przeskok do etykiety start2.
start4:
MOV A,#0x9 ;przypisanie pod akumulator A wartości 9h. SUBB A,s ;odjęcie wartości setek s od akumulator A.
JZ start5 ;skok do etykiety start5 jeśli wszystkie zadane bity są zerowe MOV d, #0x0 ;przypisanie pod zmienną d wartości 0h.
MOV t2,d ;przypisanie pod zmienną t2 wartości ze zmiennej d. INC s ;inkrementacja zmiennej s.
MOV t3,s ;przypisanie pod zmienną t3 wartości ze zmiennej s. JMP start2 ;przeskok do etykiety start2.
start5:
MOV d, #0x0 ;przypisanie pod zmienną d wartości 0h.
MOV t2,d ;przypisanie pod zmienną t2 wartości ze zmiennej d. MOV s, #0x0 ;przypisanie pod zmienną s wartości 0h.
MOV t3,s ;przypisanie pod zmienną t3 wartości ze zmiennej s. INC t ;inkrementacja zmiennej t.
MOV t4,t ;przypisanie pod zmienną t4 wartości ze zmiennej t. MOV A,#0xA=9
SUBB A,t ;odjęcie wartości tysięcy t od akumulator A.
JZ start5 ;skok do etykiety start5 jeśli wszystkie zadane bity są zerowe JMP start6 ;przeskok do etykiety start6.
start6:
MOV t1,j ;przypisanie pod zmienną t1 wartości ze zmiennej j. INC j ;inkrementacja zmiennej j.
MOV A,#0xA ;przypisanie pod akumulator A wartości Ah. SUBB A,j ;odjęcie wartości jedności j od akumulator A.
JNZ start2 ;skok do etykiety start2 jeśli nie wszystkie zadane bity są ustawione. JMP start ;przeskok do etykiety start.
END ;zakończenie wykonywania programu
Powyższy program wyświetla w oknie pamięci kolejno liczby od 1 do 9999.