Licznik BCD, AVR Asembler
Poniżej kod programu pisanego w środowisku AVR Asembler, był to
projekt na zaliczenie laboratorium architektury komputerów.
1.Temat
„Program
w assemblerze zliczający ilość zapalonych bitów na portach A,B i
przedstawiający tą ilość w systemie BCD na porcie C ”
2.Analiza,
projektowanie
Program
powinien zliczać ilość zapalonych bitów na portach A i B,
następnie przedstawić ilość tych bitów w systemie BCD. Dane z
portów wejściowych powinny być pobrane do rejestrów, następnie w
każdym rejestrze wejściowym trzeba zliczyć ilość zapalonych
bitów (1), można to zrobić za pomocą AND i przesuwania bitu w
lewo lub w prawo. W wypadku gdy AND będzie prawdziwe – zwiększany
jest licznik. W programie użyłem do tego dwóch pętli gdzie jest
najpierw liczona ilość 1 na pierwszym porcie (PORTA) a następnie,
jest porównywana rzeczywista ilość rejestrów z ilością
rejestrów sprawdzonych. W zależności od wyniku wykonywane są
instrukcje zliczania bitów następnego rejestru lub konwersja ilości
zliczonych bitów na system BCD. Takie rozwiązanie pozwala na
dodanie większej ilości portów po małych zmianach w kodzie
programu. Konwersja ilości zliczonych bitów polega na sprawdzeniu w
pierwszej kolejności czy licznik bitów jest mniejszy czy większy
bądź równy 10. Jeżeli jest mniejszy niż 10 – wyprowadzany jest
na PORT C. W przeciwnym wypadku – odejmowane jest 10 i dodawane
jest do pomocniczego rejestru 16 za każdą odjętą 10 i tak aż do
uzyskania liczby mniejszej niż 10. W przypadku tego programu –
takie rozwiązanie jest może i niepotrzebne – ale dzięki temu
można ten program bardziej rozbudować. Następnie dodawane są
wartości – rejestru pomocniczego i liczby która została po
odejmowaniu 10, wynik wyprowadzany jest na PORTC.
3.
Krótki opis używanych rejestrów
|
Rejestr
|
Nazwa
|
Opis
|
|
r20
|
we_a
|
Wejście
PORTA, później przechowuje stałą 10
|
|
r21
|
we_b
|
Wejście
PORTB
|
|
r22
|
licznik
|
Licznik
zapalonych bitów, pod koniec programu przechowuje liczbę
zapalonych bitów w BCD (dodawane są jedności + ilosc_rej_we)
|
|
r23
|
i
|
rejestr
w którym bit na najmłodszej pozycji będzie przesuwany w lewo,
rejestr ten będzie porównywany z rejestrem rej_we
|
|
r24
|
temp
|
Rejestr
pomocniczy
|
|
r25
|
rej_we
|
Tu
są przechowywane aktualne dane rejestru wejściowego w którym są
obecnie zliczane zapalone bity
|
|
r26
|
ilosc_rej_we
|
Ilość
zadeklarowanych rejestrów wejściowych, później do niego
dodawane jest 16 za każdą odjętą 10 z licznika. (domyślnie
ustawiany na 16)
|
|
r27
|
licznik_rej_we
|
Licznik
pokazujący w ilu rejestrach zostały zliczone zapalone bity,
później przechowuje stałą 16
|
4.
Kod programu
#include "8515def.inc".def we_a = r20 //wejscie PORTA, a potem wykorzystywane do przechowywania stałej 10.def we_b = r21 //wejscie PORTB.def licznik = r22 //licznik zapalonych bitów.def i = r23 //rejestr w którym bit na najmłodszej pozycji będzie przesuwany w lewo.def temp = r24 //pomocnicza.def rej_we = r25 //obecny rejestr w którym są zliczane zapalone bity.def ilosc_rej_we = r26 //początkowa ilosc rejestrów wejsciowych.def licznik_rej_we = r27 //licznik rejestrów wejsciowych
rjmp start
start:in we_a,PORTAin we_b,PORTBldi ilosc_rej_we,2 //deklaruje ilosc rejestrów wejsciowychldi licznik,0ldi licznik_rej_we,0mov rej_we,we_apetla:ldi i,1mov temp,rej_weand temp, ibrne zwieksz //jesli zapalony bitlicz:mov temp, rej_welsl ibrcs kolejny //jesli bedzie flaga C - czyli gdy nie da się przesunąć dalej bituand temp, ibrne zwieksz //jesli bedzie zapalony bitrjmp licz //jesli nie będzie zapalonego bituzwieksz:inc licznikrjmp liczkolejny:inc licznik_rej_wecp licznik_rej_we,ilosc_rej_webrsh wynik //jeżeli na wszystkich rejestrach wejsciowych zostały zliczone zapalone bitymov rej_we,we_brjmp petlawynik:ldi we_a,10 //wykorzystuje jeden z nieużywanych już rejestrów zeby nie tworzyć kolejnegoldi ilosc_rej_we,16 //wykrzystuje kolejny z nieużywanych rejestrówldi licznik_rej_we,16sprawdz:cp licznik,we_a //sprawdzam czy licznik jest >= 10brsh konwersja //jeżeli jest >= 10rjmp koniec // jeżeli jest < 10konwersja:sub licznik,we_a //odejmij 10cp licznik,we_a //porównaj czy jest ilosc zapalonych bitów jest wieksza bądz równa 10brlo dodaj //jeśli ilosc zapalonych bitów jest mniejsza od 10add ilosc_rej_we,licznik_rej_we //dodaje 16 jeżeli wykryta została 10rjmp sprawdzdodaj:add licznik,ilosc_rej_we //dla każdej 10 dodaje 16 + wartosc licznika z jednosciamikoniec:out PORTC,licznik
Brak komentarzy:
Prześlij komentarz