Procedury arytmetyczne w języku Asembler ST7.pdf

(580 KB) Pobierz
396204246 UNPDF
Przykłady procedur realizujących podstawowe działania
arytmetyczne w języku Asembler ST7.
Podstawą działań wielu programów są różne operacje arytmetyczne wykonywane czy to na zmiennych wejściowych,
czy to na zmiennych wewnętrznych. W tym artykule opiszę propozycje procedur wykonujących podstawowe działania
arytmetyczne takie jak: dodawanie, odejmowanie, mnożenie i dzielenie, porównanie liczb oraz konwersja liczb
binarnych na dziesiętne. Artykuł napisano na podstawie noty aplikacyjne firmy STMicroelectronics „ST7 Math Utility
Routines“.
Dzielenie całkowite dwóch liczb 1-bajtowych bez znaku
Na rysunku 1 przedstawiono schemat podprogramu dzielenia dwóch liczb 1-bajtowych zamieszczonego na listingu 1.
Obie liczby muszą być większe od 0. Funkcja nie sygnalizuje faktu błędnej operacji dzielenia, to jest dzielenia przez 0.
W przypadku, gdy dzielna lub dzielnik nie są właściwe, wynikiem działania jest 0 i funkcja kończy pracę. Wykonywana
jest operacja dzielenia liczb całkowitych liczba_a / liczba_b . Rezultatem działania jest wynik zapamiętany w
zmiennych iloraz i reszta .
Rysunek 1. Schemat działania podprogramu dzielenia liczb 1-bajtowych.
J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7”
str. 1/16
396204246.013.png 396204246.014.png 396204246.015.png
;*******************************************************
;dzielenie liczba_a / liczba_b
;argumenty:
; - liczba_a = dzielną
; - liczba_b = dzielnik
; - liczba_a i liczba_b ≠ 0
; - cnt (jako licznik działań)
;rezultaty:
; - iloraz zawiera część całkowitą z ilorazu liczb
; - reszta zawiera resztę z dzielenia
;modyfikowane:
; - zmienna licznikowa cnt
; - flagi Z, C
;
;PRZYKŁAD UŻYCIA
; ld A,#$E7
; ld liczba_a,A
; ld A,#$10 |
; ld liczba_b,A
; call div_ab
;*******************************************************
.div_ab
;inicjacja zmiennych
push A ;zapamiętanie akumulatora
clr iloraz ;część całkowita = 0
clr reszta ;reszta z dzielenia = 0
;sprawdzenie, czy liczba_a i liczba_b ≠ 0
ld A,liczba_b
jrugt dziel0 ;jeśli liczba_b ≠ 0, to sprawdzenie liczba_a
end_dziel
pop A ;koniec pracy podprogramu, odtworzenie akumulatora
ret
dziel0
ld A,number_a ;jeśli A=0, to wynik również = 0
jreq end_div ;jeśli A≠0, to wykonaj działania
;podprogram wykonujący dzielenie
rcf ;flaga C=0
ld A,#$08 ;inicjacja licznika przesunięć liczby
ld cnt,A
ld A,liczba_a
rlc A ;przesunięcie w lewo i zapamiętanie rezultatu
ld iloraz,A
dziel1
ld A,reszta
rlc A ;resztę z dzielenia w lewo, aby uwzględnić flagę C
ld reszta,A
sub A,liczba_b
jrc dziel2 ;kontynuacja pracy?
ld reszta,A
dziel2
ld A,iloraz
rlc A ;przesunięcie w lewo ilorazu
ld iloraz,A
dec cnt
jreq dziel3 ;jeśli licznik przesunięć=0, to koniec pracy
jra dziel1
dziel3
cpl A ;negowanie wyniku (ilorazu)
ld iloraz,A ;zapamiętanie ilorazu
jra end_dziel ;koniec pracy funkcji
Listing 1. Podprogram dzielenia dwóch liczb 1-bajtowych.
J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7”
str. 2/16
396204246.016.png 396204246.001.png 396204246.002.png
Mnożenie całkowitych liczb 1-bajtowych bez znaku
Prezentowany na listingu 2 podprogram mnoży przez siebie dwie liczby 1-bajtowe. ST7 zawiera na swojej liście
rozkazów polecenie mnożenia dwóch liczb, jednak trzeba pamiętać o tym, że wynik mnożenia (iloczyn) może być
liczbą 2-bajtową, inaczej niż czynniki. W związku z tym polecenie mnoży zawartość rejestru indeksowego X lub Y
(opB) przez zawartość akumulatora (A), a wynik umieszcza w parze rejestrów: odpowiednio X i Y, lub Y i A.
Akumulator zawiera mniej znaczący bajt iloczynu, natomiast rejestr indeksowy – bardziej znaczący. Uproszczony
schemat funkcjonowania polecenia MUL umieszczono na rysunku 2.
symbol X , oznacza polecenie MUL
(z listy rozkazów ST7) mnożące
A (akumulator)
dwie liczby 1-bajtowe
X
opB (X lub Y)
opB X A
{opB : A}
Rysunek 2. Uproszczony schemat funkcjonowania polecenia MUL.
;*******************************************************
;mnożenie liczba_a x liczba_b
;argumenty:
; - liczba_a, liczba_b (czynniki)
;rezultaty:
; - liczba_a (młodszy bajt iloczynu)
; - liczba_b (starszy bajt iloczynu)
;modyfikowane:
; - flagi H, C
;
;PRZYKŁAD UŻYCIA:
; ld A,#$A0
; ld liczba_a,A
; ld A,#$10
; ld liczba_b,A
; call mul_ab
;*******************************************************
.mul_AB
;zapamiętanie modyfikowanych rejestrów
push X
push A
;załadowanie zmiennych
ld X,liczba_A
ld A,liczba_B
mul X,A
ld liczba_a,A
ld liczba_b,X
;odtworzenie rejestrów
pop A
pop X
;powrót z podprogramu
ret
Listing 2. Podprogram mnożenia dwóch liczb 8-bitowych
J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7”
str. 3/16
396204246.003.png 396204246.004.png 396204246.005.png
Mnożenie całkowitych liczb 2-bajtowych bez znaku
Prezentowany na listingu 3 podprogram mnoży przez siebie dwie liczby 2-bajtowe. Używane są operacje mnożenia
liczb 8 bitowych oraz dodawania z przeniesieniem. Wynik mnożenia umieszczany jest w zmiennej iloczyn o długości 4
bajtów. Uproszczony schemat działania podprogramu zamieszczono na rysunku 3.
symbol X , oznacza polecenie MUL
(z listy rozkazów ST7) mnożące
{opA}
{opA+1}
dwie liczby 1-bajtowe
X
{opB}
{opB+1}
dodawanie z przeniesieniem
{opB+1} X {opA}
{opB+1} X {opA+1}
+
opB X opA
{opB} X {opA+1}
{iloczyn}
{iloczyn+1}
{iloczyn+2}
{iloczyn+3}
Rysunek 3. Uproszczony schemat działania podprogramu mnożącego 2 liczby 2-bajtowe.
J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7”
str. 4/16
396204246.006.png 396204246.007.png 396204246.008.png 396204246.009.png
;*******************************************************
;mnożenie liczba_a * liczba_b
;czynniki są 2-bajtowe, iloczyn jest 4-bajtowy
;argumenty:
; - liczba_a, liczba_b (czynniki)
;rezultaty:
; - 4-bajtowa zmienna iloczyn
;modyfikowane:
; - flagi C, Z
;
;PRZYKŁAD UŻYCIA:
; ld A,#$F3
; ld liczba_a,A
; ld A,#$D3
; ld {liczba_a+1},A
; ld A,#$FC
; ld liczba_b,A
; ld A,#$C3
; ld {liczba_b+1},A
; call mulw_ab
;*******************************************************
.mulw_ab
push A ;zapamiętanie na stosie modyfikowanych rejestrów
push X
ld X,liczba_b ;załadowanie liczb do mnożenia, bardziej znaczący
ld A,liczba_a ;bajt
mul X,A ;mnożenie liczb
ld iloczyn,X ;zapamiętanie iloczynu starszych bajtów
ld {iloczyn+1},A
ld X,{liczba_a+1} ;teraz mnożenie młodszych bajtów
ld A,{liczba_b+1}
mul X,A
ld {iloczyn+2},X ;zapamiętanie iloczynu młodszych bajtów
ld {iloczyn+3},A
ld X,liczba_a
ld A,{liczba_b+1} ;teraz mnożenie „na krzyż“ (patrz rysunek 3)
mul X,A
add A,{iloczyn+2} ;dodanie do poprzednio otrzymanych wartości
ld {iloczyn+2},A
ld A,X
adc A,{iloczyn+1}
ld {iloczyn+1},A
ld A,iloczyn
adc A,#0
ld iloczyn,A
ld X,liczba_b
ld A,{liczba_a+1} ;ponownie (następne bajty) mnożenie „na krzyż“
mul X,A
add A,{iloczyn+2} ;dodanie do poprzedniego wyniku
ld {iloczyn+2},A
ld A,X
adc A,{iloczyn+1}
ld {iloczyn+1},A
ld A,iloczyn
adc A,#0
ld iloczyn,A
pop X ;odtworzenie wartości rejestrów sprzed wywołania
pop A
ret ;koniec
Listing 3. Podprogram mnożenia dwóch liczb 2-bajtowych
J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7”
str. 5/16
396204246.010.png 396204246.011.png 396204246.012.png
Zgłoś jeśli naruszono regulamin