poniedziałek, 3 czerwca 2013

Licznik BCD, AVR Asembler

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,PORTA
in we_b,PORTB
ldi ilosc_rej_we,2 //deklaruje ilosc rejestrów wejsciowych
ldi licznik,0
ldi licznik_rej_we,0
mov rej_we,we_a
petla:
ldi i,1
mov temp,rej_we
and temp, i
brne zwieksz //jesli zapalony bit
licz:
mov temp, rej_we
lsl i
brcs kolejny //jesli bedzie flaga C - czyli gdy nie da się przesunąć dalej bitu
and temp, i
brne zwieksz //jesli bedzie zapalony bit
rjmp licz //jesli nie będzie zapalonego bitu
zwieksz:
inc licznik
rjmp licz
kolejny:
inc licznik_rej_we
cp licznik_rej_we,ilosc_rej_we
brsh wynik //jeżeli na wszystkich rejestrach wejsciowych zostały zliczone zapalone bity
mov rej_we,we_b
rjmp petla
wynik:
ldi we_a,10 //wykorzystuje jeden z nieużywanych już rejestrów zeby nie tworzyć kolejnego
ldi ilosc_rej_we,16 //wykrzystuje kolejny z nieużywanych rejestrów
ldi licznik_rej_we,16
sprawdz:
cp licznik,we_a //sprawdzam czy licznik jest >= 10
brsh konwersja //jeżeli jest >= 10
rjmp koniec // jeżeli jest < 10
konwersja:
sub licznik,we_a //odejmij 10
cp licznik,we_a //porównaj czy jest ilosc zapalonych bitów jest wieksza bądz równa 10
brlo dodaj //jeśli ilosc zapalonych bitów jest mniejsza od 10
add ilosc_rej_we,licznik_rej_we //dodaje 16 jeżeli wykryta została 10
rjmp sprawdz
dodaj:
add licznik,ilosc_rej_we //dla każdej 10 dodaje 16 + wartosc licznika z jednosciami
koniec:
out PORTC,licznik

Brak komentarzy:

Prześlij komentarz