background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 1/16 

 

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,  ode

jmowanie,  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  dz

ielenia  liczb  całkowitych  liczba_a  /  liczba_b.  Rezultatem  działania  jest  wynik  zapamiętany  w 

zmiennych iloraz reszta

 

Rysunek 1. 

Schemat działania podprogramu dzielenia liczb 1-bajtowych. 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 2/16 

 ;******************************************************* 
 ;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 

 

 

;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 

 

 

;przesunięcie w lewo ilorazu 

 

ld 

iloraz,A 

 

dec 

cnt 

 

jreq  dziel3  

 

;jeśli licznik przesunięć=0, to koniec pracy 

 

jra 

dziel1 

 dziel3 
 

cpl 

 

 

;negowanie wyniku (ilorazu) 

 

ld 

iloraz,A 

 

;zapamiętanie ilorazu 

 

jra 

end_dziel 

 

;koniec pracy funkcji 

 
 
 

Listing 1. 

Podprogram dzielenia dwóch liczb 1-bajtowych. 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 3/16 

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   

 

dwie liczby 1-bajtowe 

 
 

 

 

 

 

 

 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

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 

 

pop 

 ;powrót z podprogramu 
 

ret 

 

Listing 2. 

Podprogram mnożenia dwóch liczb 8-bitowych

opB (X lub Y) 

A (akumulator) 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 4/16 

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. W

ynik 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   

 

dwie liczby 1-bajtowe 

 
 

 

 

 

 
 
 
 
 
 

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. 

 
 

 

{opA} 

{opA+1} 

{opB} 

{opB+1} 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 5/16 

 ;******************************************************* 
 ;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 

 

 

;odtworzenie wartości rejestrów sprzed wywołania 

 

pop 

 

ret 

 

 

 

;koniec 

 
 

Listing 3. 

Podprogram mnożenia dwóch liczb 2-bajtowych 

 
 
 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 6/16 

Dzielenie całkowite liczby 4-bajtowej przez 2-bajtową 

Na  rysunku  4  przestawiono  schemat  podprogramu  dzielenia  liczby  4-bajtowej  przez  2-

bajtową.  Iloraz  otrzymany  w 

wyniku  dzielenia  zapisywany  jest  w  zmiennej  2  bajtowej

,  więc  tak  naprawdę  funkcja  znajdzie  zastosowanie  tylko  w 

przypadkach,  gdy  iloraz  jest mniejszy  od  65536.  Zmienne  nazywają  się  tak, jak  składniki  operacji:  dzielna,  dzielnik, 
iloraz. Pozwoli to na ich łatwe rozróżnienie. Podprogram umieszczono na listingu 4. 

 
 
Rysunek 4.
 Schemat podprogramu dzielenia liczby 4-bajtowej przez 2-

bajtową 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 7/16 

 ;******************************************************* 
 ;Dzielenie liczby typu LONG przez liczbę typu WORD 
 ;argumenty: 
 ; - dzielna (4 bajty) 
 ; - dzielnik (2 bajty) 
 ;rezultaty: 
 ; - 2-bajtowa zmienna iloraz 
 ;modyfikowane: 
 ; - flagi C, Z 
 ; - wewnętrzna zmienna tmp 
 ; 
 ;PRZYKŁAD UŻYCIA: 
 ; 

ld 

A,#$0E 

 ; 

ld  

dzielna,A 

 ; 

ld  

A,#$DC 

 ; 

ld  

{dzielna+1},A 

 ; 

ld  

A,#$BA 

 ; 

ld  

{dzielna+2},A 

 ; 

ld  

A,#$98 

 ; 

ld  

{dzielna+3},A 

 ; 

ld  

A,#$AB 

 ; 

ld  

dzielnik,A 

 ; 

ld  

A,#$CD 

 ; 

ld  

{dzielnik+1},A 

 ; 

call  div_lw | 

 ;******************************************************* 
 
 .div_lw 
 

push  A 

 

 

 

;zapamiętanie rejestrów roboczych na stosie 

 

push  X 

 

ld 

X,#32   

 

 

;inicjacja zmiennych 

 

ld 

A,#0   

 

 

;instrukcja LD zajmuje więcej miejsca, niż CLR 

 

ld 

iloraz,A 

 

 

;jednak działa znacznie szybciej 

 

ld 

{iloraz+1},A 

 

ld 

tmp,A 

 

ld 

{tmp+1},A 

 

ld 

{tmp+2},A 

 

ld 

{tmp+3},A 

 .wykonaj 
 

sla 

{dzielna+3}   

 

;przesunięcie dzielnej w lewo bez C 

 

rlc 

{dzielna+2} 

 

rlc 

{dzielna+1} 

 

rlc 

dzielna 

 

rlc 

{tmp+3} 

 

 

;przesunięcie w lewo zmiennej pomocnicznej 

 

rlc 

{tmp+2} 

 

rlc 

{tmp+1} 

 

rlc 

tmp 

 

sla 

{iloraz+1} 

 

 

;wynik nie może mieć więcej, niż 16 bitów, więc 

 

rlc 

iloraz  

 

 

;można przesuwać w prawo iloraz 

 

ld 

A,tmp   

 

 

;sprawdzenie, czy dzielna jest większa, czy równa  

 

 

 

 

 

 

;od dzielnika 

 

or 

A,{tmp+1} 

 

jrne  div_lw_odejmij 

 

ld 

A,{tempquot+2} 

 

cp 

A,divisor 

 

jrugt  divlw_odejmij 

 

jrult  divlw_bez_odejmowania 

 

ld 

A,{tmp+3} 

 

cp 

A,{dzielnik+1} 

 

jrult  divlw_bez_odejmowania 

 .divlw_odejmij  

 

 

 

;odejmowanie dzielnika od dzielnej  

 

ld 

A,{tmp+3} 

 

sub 

A,{dzielnik+1} 

 

ld 

{tmp+3},A 

 

ld 

A,{tmp+2} 

 

sbc 

A,dzielnik 

 

ld 

{tmp+2},A 

 

ld 

A,{tmp+1} 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 8/16 

 

sbc 

A,#0 

 

ld 

{tmp+1},A 

 

ld 

A,tmp 

 

sbc 

A,#0 

 

ld 

tmp,A 

 

inc 

{iloraz+1} 

 

;zwiększenie ilorazu 

 

jrne  divlw_bez_odejmowania 

 

inc 

iloraz 

 .divlw_bez_odejmowania 
 

dec 

 

 

;zmniejszenie licznika „przejść“ pętli 

 

jrne  wykonaj  

 

;jeśli licznik = 0,to koniec inaczej kontynuacja 

 

pop 

 

 

;odtworzenie wartości rejestrów 

 

pop 

 

ret 

 

 

 

;koniec 

 
 

Listing 4. Podprogram dzielenia liczby 4-bajtowej przez 2-

bajtową. 

 
 
 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 9/16 

Dodawanie dwóch liczb 2-bajtowych bez znaku 

Dodawanie  dwóch  liczb  bez  znaku,  nawet  o  dużej  liczbie  bajtów,  jest  bardzo  proste.  Wystarczy  dodawać  bajt  po 
bajcie  poczynając  od  najmłodszego  bajtu,  uwzględniając  przeniesienie.  Do  zapamiętania  wyniku  dodawania 
wystarczająca  jest  taka  liczba  bajtów,  jakiej  jest  długość  najdłuższego  ze  składników  i  flaga  przeniesienia.  Dla 
opisywanego podprogramu są to dokładnie 2 bajty i flaga C (maksimum to $FFFF+$FFFF=$1FFFE, cyfra 1 może być 
reprezentowana  przez  flagę  przeniesienia  C).  Podprogram  umieszczono  na  listingu  5.  Suma  zapamiętywana  jest  w 
zmiennej sumaw

, ale równie dobrze można wykorzystać do zapamiętania wyniku jeden ze składników. 

 

 

 ;******************************************************* 
 ;Dodawanie 2 liczb 2-bajtowych bez znaku 
 ;argumenty: 
 ; - add_a (2 bajty) 
 ; - add_b (2 bajty) 
 ;rezultaty: 
 ; - wynik zapamiętywany w sumaw 
 ;modyfikowane: 
 ; - flaga C 
 ; 
 ;PRZYKŁAD UŻYCIA: 
 ; 

ld  

A,#$F3 

 ; 

ld 

add_a,A 

 ; 

ld 

A,#$D3 

 ; 

ld 

{add_a+1},A 

 ; 

ld 

A,#$FC 

 ; 

ld 

add_b,A 

 ; 

ld 

A,#$C3 

 ; 

ld 

{add_b+1},A 

 ; 

call  addw 

 ;******************************************************* 
 
 .addw 
 

push  A 

 

 

;zapamiętanie rejestrów roboczych 

 

push  X 

 

ld 

A,{add_a+1}    

;pobranie młodszego liczby a 

 

add   A,{add_b+1}   

;dodanie młodszego liczby b 

 

ld  

{sumaw+1},A   

;zapamiętanie młodszego bajtu sumy 

 

ld  

A,add_a  

 

;pobranie starszego bajtu liczby a 

 

adc   A,add_b  

 

;dodanie przeniesienia i starszego bajtu liczby b 

 

ld  

sumaw,A  

 

;zapamiętanie starszego bajtu sumy 

 

pop   X  

 

 

;odtworzenie rejestrów 

 

pop   A 

 

ret 

 
 

Listing 5. 

Podprogram dodawania dwóch liczb 2-bajtowych bez znaku. 

 
 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 10/16 

Odejmowanie dwóch liczb 2-bajtowych bez znaku 

Przy odejmowaniu liczb o większej liczbie bajtów należy postępować dokładnie tak samo, jak w przypadku 
dodawania. Począwszy od najmłodszego bajtu odejmować z pożyczką bajt po bajcie. Rozmiar wyniku ponownie jest 
taki sam, jak długość najdłuższej liczby. Flaga przeniesienia sygnalizuje, czy odjemna jest większa odjemnika, czy też 
mniejsza. Przykładowy podprogram odejmowania umieszczono na listingu 6. 
 

 

 ;******************************************************* 
 ;Odejmowanie 2 liczb 2-bajtowych bez znaku 
 ;argumenty: 
 ; - sub_a (odjemna,2 bajty) 
 ; - sub_b (odjemnik,2 bajty) 
 ;rezultaty: 
 ; - wynik zapamiętywany w roznicaw 
 ;modyfikowane: 
 ; - flaga C 
 ; 
 ;PRZYKŁAD UŻYCIA: 
 ; 

ld  

A,#$F3 

 ; 

ld 

sub_a,A 

 ; 

ld 

A,#$D3 

 ; 

ld 

{sub_a+1},A 

 ; 

ld 

A,#$FC 

 ; 

ld 

sub_b,A 

 ; 

ld 

A,#$C3 

 ; 

ld 

{sub_b+1},A 

 ; 

call  subw 

 ;******************************************************* 
 
 .subw 
 

push  A 

 

 

;zapamiętanie rejestrów roboczych 

 

push  X 

 

ld 

A,{sub_a+1}   

;pobranie młodszego liczby a 

 

sub   A,{sub_b+1}   

;dodanie młodszego liczby b 

 

ld  

{roznicaw+1},A  

;zapamiętanie młodszego bajtu różnicy 

 

ld  

A,sub_a  

 

;pobranie starszego bajtu liczby a 

 

sbc   A,sub_b  

 

;odjęcie przeniesienia i starszego bajtu liczby b 

 

ld  

roznicaw,A    

;zapamiętanie starszego bajtu roznicy 

 

pop   X  

 

 

;odtworzenie rejestrów 

 

pop   A 

 

ret 

 

Listing 6. Podprogra

m odejmowania dwóch liczb 2-bajtowych bez znaku. 

 
 
 
 
 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 11/16 

Sprawdzenie, czy liczba 2-

bajtowa bez znaku mieści się w podanym zakresie 

Podprogram sprawdza, czy liczba 2-

bajtowa znajduje się w zadanym zakresie wartości. Zmienna data zawiera liczbę 

do  przetestowania,  zmienna  min 

określa  wartość  minimalną  a  max  –  maksymalną.  Stan  flagi  C  po  opuszczeniu 

podprogramu  jest  zależny  od  rezultatu  testu.  Wartość  logiczna  flagi  C  równa  „0“  oznacza,  że  testowana  zmienna 
mieści się w zakresie od min do max, natomiast wartość „1“ oznacza, że leży poza nim. Na rysunku 7 umieszczono 
schemat podprogramu test

ującego, natomiast listing 7 zawiera jego kod źródłowy. 

 
Rysunek 7. 

Schemat podprogramu testującego, czy zmienna leży w zakresie od min do max 

 
 
 
 
 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 12/16 

;******************************************************* 
 ;Testowanie, czy zmienna (data > min) i (data < max) 
 ;argumenty: 
 ; - data (2 bajty,testowana liczba) 
 ; - min (wartość minimalna,2 bajty) 
 ; - max (wartość maksymalna, 2 bajty) 
 ;rezultaty: 
 ; - C=0, gdy min < data < max inaczej C=1 
 ;modyfikowane: 
 ; - flaga C 
 ; 
 ;PRZYKŁAD UŻYCIA: 
 ; 

ld  

A,#$25 

 ; 

ld  

data,A 

 ; 

ld  

A,#$00 

 ; 

ld  

{data+1},A 

 ; 

ld  

A,#$00 

 ; 

ld  

min,A 

 ; 

ld  

A,#$C3 

 ; 

ld  

{min+1},A 

 ; 

ld  

A,#$CC 

 ; 

ld  

max,A 

 ; 

ld  

A,#$05 

 ; 

ld  

{max+1},A 

 ; 

call  check_min_max 

 ;******************************************************* 
 .check_min_max 
 

push  A 

 

 

;zapamiętanie rejestrów roboczych 

 

push  X 

 

ld 

X,data  

 

;pobranie do X bardziej znaczącego bajtu do testu 

 

ld 

A,{data+1} 

 

;pobranie do A mniej znaczącego bajtu 

 

cp 

X,max   

 

;porównanie bardziej znaczącego bajtu z max (maksimum) 

 

jrugt  out_of_range  

 

;jeśli większy, to wyjście 

 

jrne  comp_min  

 

;jeśli równy, to porównanie mniej znaczącego bajtu 

 

cp 

A,{max+1} 

 

jrugt  out_of_range  

 

;mniej znaczący bajt większy - wyjście 

 comp_min 
 

cp 

X,min   

 

;to samo dla wartości minimalnej min 

 

jrult  out_of_range 

 

jrne  in_range 

 

cp 

A,{min+1} 

 

jrult  out_of_range 

 in_range 
 

rcf 

 

 

 

;zmienna mieści się w zakresie – C=0 

 

jra   check_exit 

 out_of_range 
 

scf    

 

 

;zmienna poza zakresem – C=1 

 check_exit 
 

pop   X  

 

 

;odtworzenie rejestrów roboczych 

 

pop   A 

 

ret 

 
 

Listing 7. 

Podprogram testujący, czy liczna mieści się w zakresie od min do max 

 
 
 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 13/16 

Sprawdzenie odchylenia od środkowej liczby 2-bajtowej 

Funkcjonalnie  podprogram  jest  bardzo  zbliżony  do  poprzednio  prezentowanego.  Poprzedni  testował,  czy  zmienna 
mieści się w  zakresie min  – max, ten sprawdza  –  po podaniu  parametrów:  środkowadelta (odchylenie)  i  zmiennej 
data 

– czy zmienna nie przekracza zadanego odchylenia delta. Podprogram kończy pracę sygnalizując rezultat testu 

przy  pomocy flagi  przeniesienia C. Gdy  ta jest ustawiona, to  zmienna przekracza  zadane odchylenie, natomiast gdy 
jest zerem, to zmienna mieści się w zakresie srodkowa-delta data srodkowa+delta. 

 
Rysunek 8. 

Schemat podprogramu testującego, czy zmienna mieści się w zakresie odchyłki środkowa ± Δ

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 14/16 

 ;*******************************************************

 

 ;Testowanie, czy zmienna (data > środkowa-delta) i  
 ;(data < środkowa+delta) 
 ;argumenty: 
 ; - data (2 bajty,testowana liczba) 
 ; - delta (wartość odchylenia,2 bajty) 
 ; - srodkowa (wartość środkowa, 2 bajty) 
 ;rezultaty: 
 ; - C=0, gdy zmienna nie przekracza odchylenia, inaczej C=1 
 ;modyfikowane: 
 ; - flaga C 
 ; 
 ;PRZYKŁAD UŻYCIA 
 ; 

ld 

A,#$25 

 ; 

ld 

data,A 

 ; 

ld 

A,#$00 

 ; 

ld 

{data+1},A 

 ; 

ld 

A,#$00 

 ; 

ld 

delta,A 

 ; 

ld 

A,#$23 

 ; 

ld 

{delta+1},A 

 ; 

ld 

A,#$CC 

 ; 

ld 

srodkowa,A 

 ; 

ld 

A,#$05 

 ; 

ld 

{srodkowa+1},A 

 ; 

call  check_range 

 ;******************************************************* 
 .check_range 
 

push   X 

 

 

;zapamiętanie rejestrów roboczych 

 

push   A 

 

ld  

A,srodkowa    

;pobranie starszego bajtu wartości środkowej i 

 

ld  

add_a,A  

 

;zapamiętanie jej w zmiennych add_a i sub_a 

 

ld  

sub_a,A  

 

;dla podprogramów addw i subw 

 

ld  

A,{srodkowa+1} 

;to samo dla młodszego bajtu 

 

ld  

{add_a+1},A 

 

ld  

{sub_a+1},A 

 

ld  

A,delta  

 

;to samo dla delta, ale w zmiennych add_b i sub_b 

 

ld  

add_b,A 

 

ld  

sub_b,A 

 

ld  

A,{delta+1} 

 

ld  

{add_b+1},A 

 

ld  

{sub_b+1},A 

 

call   addw    

 

;obliczenie sumy srodkowa + delta 

 

jrnc   no_ovfmax  

 

;jeśli przekroczono zakres,to ustaw wartość MAX na  

 

ld  

A,#$FF  

 

;$FFFF (maksymalna dla 2 bajtów) 

 

ld  

max,A 

 

ld  

{max+1},A 

 no_ovfmax 
 

ld  

A,res_add  

 

;jeśli nie ma przekroczenia zakresu, to wówczas 

 

ld  

max,A   

 

;za maksimum przyjmij wyliczoną wartość 

 

ld  

A,{res_add+1} 

 

ld  

{max+1},A 

 

call   subw    

 

;obliczenie wartości srodkowa-delta 

 

jrnc   no_ovfmin  

 

;jeśli wystąpiło przeniesienie, to wartość minimum 

 

clr   A  

 

 

;ustaw na 0 

 

ld  

min,A 

 

ld  

{min+1},A 

 no_ovfmin 
 

ld  

A,res_sub  

 

;jeśli nie ma przeniesienia,to za minimum przyjmij 

 

ld  

min,A   

 

;wyliczoną w wyniku odejmowania wartość 

 

ld  

A,{res_sub+1} 

 

ld  

{min+1},A 

 

call   check_min_max  

;wywołaj podprogram i sprawdź, czy zmienna jest w 

 

 

 

 

 

;zakresie ustalonym przez MIN i MAX 

 

pop 

 

 

;odtworzenie rejestrów roboczych 

 

pop 

 

ret 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 15/16 

Listing 8. 

Podprogram sprawdzający, czy zmienna mieści się w zakresie środkowa ± Δ 

Konwersja liczb binarnych na dziesiętne. 

Podprogram wykonuje konwersję liczby binarnej bez znaku zawartej w akumulatorze, to jest z zakresu od 0 do 255, 
na liczbę dziesiętną. Po zakończeniu zmienne setki i dziesiatki zawierają wartości w kodzie BCD otrzymane w wyniku 
konwersji (zmienna setki 

zawiera cyfrę setek, zmienna dziesiatki cyfry dziesiątek i jedności). Schemat funkcjonowania 

podprogramu umieszczono na rysunku 9, a listing 9 

zawiera jego kod źródłowy. 

 
 
Rysunek 9.
 

Schemat podprogramu konwersji liczby binarnej na dziesiętną 

 
 

 

 

 

background image

 
 

 
 

J.Bogusz „Podstawowe działania arytmetyczne w asemblerze ST7” 

str. 16/16 

 ;******************************************************* 
 ;Konwersja liczby 1-bajtowej, binarnej na dziesiętną 
 ;argumenty: 
 ; - liczba w akumulatorze 
 ;rezultaty: 
 ; - setki: cyfra setek 
 ; - dziesiątki: cyfra dziesiątek i jednostek 
 ;modyfikowane: 
 ; - flaga C, Z, zmienne wyniku 
 ; 
 ;PRZYKŁAD UŻYCIA 
 ; 

ld  

A,#$D4 

 ; 

call  BtoD 

 .BtoD 
 

clr 

setki   

 

;inicjacja zmiennych 

 

clr 

dziesiatki 

 hund 
 

sub 

A,#100  

 

;A = A - 100 

 

jrc 

ten    

 

;sprawdzenie, czy A < 100 

 

inc 

hundreds  

 

;jeśli nie, to zwiększanie licznika setek 

 

jra 

hund    

 

;pętla do spełnienia w/w warunku 

 ten 
 

add 

A,#100  

 

;dodanie 100, aby uzupełnić A po ostatniej operacji 

 temp   

 

 

 

;(nastąpiło przekroczenie zakresu) 

 

sub 

A,#10   

 

;A = A - 10 

 

jrc 

unit    

 

;jak w przypadku setek – sprawdzenie, czy A < 10 

 

inc 

tens    

 

;i jeśli nie, to zwiększanie licznika 10-tek 

 

jra 

temp    

 

;pętla do spełnienia w/w warunku 

 unit  
 

add 

A,#10   

 

;dodanie 10, aby uzupełnić A po ostatnim odejmowaniu 

 

swap   tens    

 

;zamiana połówek bajtu tak, aby bardziej znaczący bajt  

 

 

 

 

 

;zawierał cyfrę dziesiątek 

 

or  

A,tens  

 

;dodanie jednostek (A zawiera jednostki po odejmowaniu 

 

ld  

tens,A  

 

;setek i dziesiątek) 

 

ret 

 

Listing 9. Konwersja liczby 1-

bajtowej w kodzie binarnym na dziesiątną.