POLITECHNIKA LUBELSKA
Wydział Elektrotechniki i Informatyki
LABORATORIUM PROGRAMOWANIA
NISKOPOZIOMOWEGO
Ćwiczenie nr : 3
Temat : Podstawowe operacje arytmetyczne.
Grupa:
Data wykonania:
Wykonał:
Zadanie 1
(operacja dodawania z wykorzystaniem bitu przeniesienia C i wyświetlanie wyników w kodzie dziesiętnym BCD)
Listing programu:
1 LJMP START
2 ORG 100H
3 START:
4 LCALL LCD_CLR
5
6 MOV A,#240
7 LCALL BIN_BCD
8 MOV R0,A
9
10 MOV A,#'+'
11 LCALL WRITE_DATA
12 CLR C
13
14 MOV A,#100
15 LCALL BIN_BCD
16 MOV R1,A
17
18 MOV A,#'='
19 LCALL WRITE_DATA
20 CLR C
21
22 MOV A,R1
23 ADDC A,R0
24
25 JNC POINTER
26
27 MOV B,#100
28 ADD A,#56
29 DIV AB
30 ADD A,#2
31 LCALL WRITE_HEX
32 MOV A,B
33
34 POINTER:
35 LCALL BIN_BCD
36
37 LJMP $
38
39 BIN_BCD:
40 PUSH PSW
41 PUSH B
42 PUSH ACC
43
44
45 MOV B,#100
46 DIV AB
47
48 JZ POINTER1
49 LCALL WRITE_HEX
50
51 POINTER1:
52 MOV A,B
53 MOV B,#10
54 DIV AB
55 SWAP A
56 ADD A,B
57
58 LCALL WRITE_HEX
59
60 POP ACC
61 POP B
62 POP PSW
63
64 RET
Wnioski:
Program sumuje dwie liczby z zakresu 0..256.
W wierszach 6-20 następuje wpisanie do rejestrów składników i wywołanie podprogramu BIN_BCD który zamienia składniki na kod BCD i wypisuje je w postaci dziesiętnej.
Zostają również wyświetlone znaki + i = .
W przypadku gdy suma jest większa niż 256 zostaje ustawiony bit przeniesienia C czyli siódmy bit rejestru stanu PSW. Aby przy dodawaniu uwzględnić ustawianie tego bitu należy zamiast rozkazu ADD użyć rozkazu ADDC jak w wierszu 23.
Jeżeli po wykonaniu operacji dodawania wartość bitu przeniesienia wynosi 0 to zostaje wykonany skok do miejsca oznaczonego etykietą POINTER.
Wówczas należy wywołać BIN_BCD aby zamienić wynik na BCD i wyświetlić go jako liczbę dziesiętną.
Do sprawdzenia stanu bitu C został użyty w wierszu 25 rozkaz JNC wykonujący skok do etykiety podanej jako parametr jeśli stwierdzi C=0.
Jeśli C=1 to zostaną wykonane instrukcje z wierszy 27-32. Służą one do obliczenia i wyświetlenia liczby setek.
Od wartości przeniesienia 256 zostaje odrzucona liczba setek czyli 2. Liczbę 56 należy dodać do zawartości akumulatora i podzielić przez 100. Do części całkowitej z podziału przez 100, która znajduje się w akumulatorze jest dodana 2 i całość wyświetlona jako liczba setek końcowej sumy. Należy jeszcze przenieść resztę z dzielenia przez 100 z rejestru B do akumulatora.
Podprogram BIN_BCD rozpoczyna się od zachowania na stosie rejestrów PSW, B i A, aby po wykonaniu podprogramu można je było powtórnie odczytać.
Aby sprawdzić czy dana liczba jest trzycyfrowa należy podzielić ją przez 100 i sprawdzić stan akumulatora rozkazem JZ. Zero oznacza liczbę dwucyfrową lub cyfrę i zostaje wykonany skok do POINTER1. W ten sposób zostaje pominięty rozkaz LCALL WRITE_HEX z wiersza 49, który niepotrzebnie wyświetlałby dwa zera.
Na koniec zostają odczytane ze stosu wartości PWD,B i A.
Zadanie 2:
(odejmowanie z uwzględnieniem liczb ujemnych)
Listing programu:
1 LJMP START
2 ORG 100H
3 START:
4 LCALL LCD_CLR
5
6 MOV A,#255
7 LCALL BIN_BCD
8 MOV R0,A
9
10 MOV A,#'-'
11 LCALL WRITE_DATA
12 CLR C
13
14 MOV A,#100
15 LCALL BIN_BCD
16 MOV R1,A
17
18 MOV A,#'='
19 LCALL WRITE_DATA
20 CLR C
21
22 MOV A,R0
23 SUBB A,R1
24 JNC POINTER
25 PUSH ACC
26 MOV A,#'-'
27 LCALL WRITE_DATA
28 POP ACC
29
30 MOV R0,A
31 MOV A,#255
32 SUBB A,R0
33 ADD A,#2
34
35
36 POINTER:
37 LCALL BIN_BCD
38
39 SJMP $
40
41
42 BIN_BCD:
43 PUSH ACC
44 PUSH PSW
45
46 MOV B,#100
47 DIV AB
48 JZ POINT
49 LCALL WRITE_HEX
50 POINT:
51 MOV A,B
52 MOV B,#10
53 DIV AB
54 SWAP A
55 ADD A,B
56 LCALL WRITE_HEX
57 POP PSW
58 POP ACC
59 RET
Wnioski:
Program odejmuje jedną liczbę od drugiej uwzględniając liczby ujemne oraz wyświetla różnicę w postaci dziesiętnej.
W wierszach 6-20 następuje wpisanie do rejestrów odjemnej, odjemnika i wywołanie podprogramu BIN_BCD który zamienia odjemną i odjemnik na kod BCD i wypisuje je w postaci dziesiętnej.
Zostają również wyświetlone znaki - i = .
Przy posługiwaniu się rozkazem odejmowania SUBB bit C pełni rolę pożyczki i musi być zerowany przed wykonaniem odejmowania. Nie wyzerowanie bitu C prowadzi do otrzymania błędnego wyniku. Jeżeli po wykonaniu odejmowania bit C zmienił swoją wartość na 1 oznacza to, iż otrzymana różnica jest ujemna.
Rozkaz odejmowania jest zapisany w wierszu 23. Następnie jest sprawdzana wartość bitu C rozkazem JNC.
Jeśli C=0 to następuje skok do etykiety POINTER: i zamienia się różnicę na BCD korzystając z BIN_BCD.
Jeśli C=1 to zawartość akumulatora jest dodana do stosu poleceniem PUSH aby umożliwić wstawienie do akumulatora a następnie wypisanie znaku - . Następnie odzyskuje się wartość akumulatora przechowywaną na stosie poleceniem POP.
Odejmując od 255 wartość z akumulatora i dodając 2 uzyskuje się liczbę dodatnią, która odpowiada wartości bezwzględnej z ujemnej różnicy dwóch liczb. Teraz należy już tylko skorzystać z BIN_BCD.
Zadanie 4:
(mnożenie)
Listing programu:
1 LJMP START
2 ORG 100H
3 START:
4 LCALL LCD_CLR
5
6 MOV A,#255
7 LCALL BIN_BCD
8 MOV R0,A
9
10 MOV A,#'*'
11 LCALL WRITE_DATA
12
13
14 MOV A,#255
15 LCALL BIN_BCD
16 MOV B,A
17
18 MOV A,#'='
19 LCALL WRITE_DATA
20
21
22 MOV A,R0
23 MUL AB
24
25 XCH A,B
26 LCALL WRITE_HEX
27 MOV A,B
28 LCALL WRITE_HEX
29
30
31 SJMP $
32
33
34 BIN_BCD:
35 PUSH ACC
36 PUSH PSW
37
38 MOV B,#100
39 DIV AB
40 JZ POINT
41 LCALL WRITE_HEX
42 POINT:
43 MOV A,B
44 MOV B,#10
45 DIV AB
46 SWAP A
47 ADD A,B
48 LCALL WRITE_HEX
49 POP PSW
50 POP ACC
51 RET
Wnioski:
Program mnoży dwie liczby i wypisuje iloczyn w postaci szesnastkowej.
W wierszach 6-20 następuje wpisanie do rejestrów czynników i wywołanie podprogramu BIN_BCD który zamienia czynniki na kod BCD i wypisuje je w postaci dziesiętnej.
Zostają również wyświetlone znaki * i = .
Mnożenie realizuje się za pomocą rozkazu MUL AB. Wykonuje się ono zawsze na rejestrach A i B. Wynik mnożenia może być maksymalnie 16-bitowy gdyż po wykonaniu działania mniej znacząca część iloczynu (młodsze 8 bitów) znajduje się w akumulatorze, zaś bardziej znacząca część (starsze 8 bitów) w rejestrze B.
Aby w pierwszej kolejności wyświetlić bardziej znaczący bajt użyty został w wierszu 25 rozkaz XCH, który zamienia wartości bajtów podanych jako parametry.
Następnie starszy bajt zostaje wyświetlony z akumulatora, do akumulatora zostaje podstawiony młodszy bajt z rejestru B poleceniem MOV A,B, po czym również on zostaje wyświetlony.