LABORATORIUM TECHNIKI MIKROPROCESOROWEJ |
|||||
Imię i nazwisko:
Robert Czechoński Janusz Buchoski |
Grupa:
ED5.3 |
Data:
25.10.1999 |
Nr ćwiczenia:
3B |
||
Temat: Operacje arytmetyczne
|
|||||
Przygotowanie:
|
Zaliczenie: |
Ogólna: |
Cel ćwiczenia
Celem ćwiczenia jest zapoznanie się ze sposobem wykonywania podstawowych operacji arytmetycznych na liczbach jednobajtowych oraz metod konwersji formatów stosowanych do reprezentacji danych.
Zadania ćwiczenia
Zmodyfikować program nr1 tak aby dodawał liczbę -10 do wartości pobranej z klawiatury. Narysować schemat algorytmu.
Jakie ograniczenia wynikają z zastosowania reprezentacji danych w postaci uzupełnienia do dwóch i jak można się ustrzec przed błędami wynikającymi z tych ograniczeń?
Uruchomić program nr3, zanotować stany akumulatora i rejestru B w poszczególnych krokach wykonywania programu.
Zmodyfikować program aby: dokonywał mnożenia liczb w postaci BCD, powtarzające się sekwencje instrukcji znalazły się w podprogramach.
Należy napisać i uruchomić program dokonujący konwersji liczby zapisanej w formacie spakowane BCD do postaci binarnej .
Wyniki
Program nr1.
;***********************************************;LEKCJA 3b - OPERACJE ARYTMETYCZNE;PRZYKťAD 1 - LICZBY UJEMNE U2;***********************************************
LJMP START
ORG 100H
START:
LCALL LCD_CLR
CLR A ;zeruj A
CLR C ;zeruj C
SUBB A,#1 ;A <- 0-1 = -1
MOV R0,A ;zapamiętaj w R0
LCALL WRITE_HEX
MOV A,R0 ;A <- R0=-1
ADD A,#1 ;A <- A+1 = -1+1 = 0
LCALL WRITE_HEX
SJMP $
Program działa poprawnie.
Ad 1.
Program nr2 dodaje -10 do liczby pobranej z klawiatury i wyświetla wynik na wyświetlaczu
;***********************************************;LEKCJA 3b - OPERACJE ARYTMETYCZNE;PRZYKťAD 1 - LICZBY UJEMNE U2
;************************************************
LJMP START
ORG 100H
START:
LCALL LCD_CLR
LCALL WAIT_KEY ;wczytaj z klawiatury
SUBB A,#10 ;A <- A-10
LCALL WRITE_HEX
SJMP $
Algorytm programu:
LCALL LCD_CLR ;Wyczyść wyświetlacz |
|
LCALL WAIT_KEY ;A<=: KEY |
|
SUBB A,#10 ;A<=: A-10 |
|
LCALL WRITE_HEX ;LCD<=: A |
|
PETLA: |
|
|
SJMP PETLA |
Ad2.
Podczas korzystania z zapisu w kodzie uzupełnienia do dwóch operując na pojedynczym bajcie możemy zakodować liczby w zakresie -2k≤m≤2k-1. Aby się uchronić przed błędami należy pamiętać, że najbardziej znaczący bit określa zawsze znak liczby. Należy także stale śledzić zawartość wskaźnika przepełnienia.
Ad3.
Program nr3.
;************************************************;LEKCJA 3b - OPERACJE ARYTMETYCZNE;PRZYKťAD 2 - SUMOWANIE LICZB W FORMACIE BCD;************************************************ LJMP START ORG 100HSTART: LCALL LCD_CLR
LCALL WAIT_KEY ;pobierz pierwszy czynnik
MOV B,#10 ;zamień liczbę na BCD
DIV AB ;dzieląc przez 10
SWAP A
ADD A,B
MOV R0,A ;zapamiętaj w R0 (BCD)
LCALL WRITE_HEX ;wypisz na LCD
MOV A,#'+' ;znak sumy
LCALL WRITE_DATA ;wyświetl jako znak
LCALL WAIT_KEY ;pobierz drugi czynnik
MOV B,#10 ;zamień liczbę na BCD
DIV AB ;dzieląc przez 10
SWAP A
ADD A,B
MOV R1,A ;zapamiętaj w R1 (BCD)
LCALL WRITE_HEX ;wypisz na LCD
MOV A,#'=' ;znak równości
LCALL WRITE_DATA ;wyświetl jako znak
MOV A,R0 ;pierwszy czynnik do A
ADD A,R1 ;dodaj drugi czynnik
DA A ;poprawka dodawania
;liczb BCD
LCALL WRITE_HEX ;wypisz wynik na LCD
SJMP $
instrukcja |
A |
B |
LCD |
|
|
|
|
LCALL LCD_CLR |
A0 |
34 |
_ |
LCALL WAIT_KEY |
0A |
34 |
_ |
MOV B,#10 |
0A |
0A |
_ |
DIV AB |
01 |
00 |
_ |
SWAP A |
10 |
00 |
_ |
ADD A,B |
10 |
00 |
_ |
MOV R0,A |
10 |
00 |
_ |
LCALL WRITE_HEX |
10 |
00 |
10 |
MOV A.#'+' |
2B |
00 |
10 |
LCALL WRITE_DATA |
2B |
00 |
10+ |
LCALL WAIT_KEY |
0F |
00 |
10+ |
MOV B,#10 |
0F |
0A |
10+ |
DIV AB |
01 |
05 |
10+ |
SWAP A |
10 |
05 |
10+ |
ADD A,B |
15 |
05 |
10+ |
MOV R1,A |
15 |
05 |
10+ |
LCALL WRITE_HEX |
15 |
05 |
10+15 |
MOV A,#'=' |
3D |
05 |
10+15 |
LCALL WRITE_DATA |
3D |
05 |
10+15= |
MOV A,R0 |
10 |
05 |
10+15= |
ADD A,R1 |
25 |
05 |
10+15= |
DA A |
25 |
05 |
10+15= |
LCALL WRITE_HEX |
25 |
05 |
10+15=25 |
Ad4.
Program mnoży dwie liczby a wyniki wyświetla w postaci BCD.
LJMP START ORG 100HSTART: LCALL LCD_CLR ;Wyczyść wyświetlacz
MOV A,#'>'
LCALL WRITE_DATA ;Wyświetl prompt
LCALL WAIT_KEY ;A<=KEYBOARD
MOV R0,A ;R0<=A
ACALL WRITE_BCD ;Zamień na BCD i wyświetl
MOV A,#'*'
LCALL WRITE_HEX
LCALL WAIT_KEY ;A<=KEYBOARD
MOV R1,A ;R1<=A
ACALL WRITE_BCD ;Zamień na BCD i wyświetl
MOV A,#'='
LCALL WRITE_HEX
MOV A,R0 ;A<=R0
MOV B,R1 ;B<=R0
MUL AB ;Pomnóż A z B
ACALL WRITE_BCD ;Zamień na BCD i wyświetl
SJMP $
WRITE_BCD:MOV B,#100 ;Podprogram zamienia liczbę
DIV AB ;w akumulatorze na BCD-
PUSH ACC ;setki w B, dziesiątki i jedności
MOV A,B ;w A a następnie wyświetla wynik
MOV B,#10 ;na wyświetlaczu
DIV AB
SWAP A
ORL A,B
POP B
XCH A,B
LCALL WRITE_HEX
MOV A,B
LCALL WRITE_HEX
RET
Ad 5.
Program dokonuje konwersji liczby zapisanej w formacie BCD do postaci binarnej i wyświetla ją w postaci szesnastkowej i binarnej.
LJMP START
ORG 100H
START:
LCALL LCD_CLR ;Czyścimy wyświetlacz
MOV A,#'>'
LCALL WRITE_DATA ;Wyświetlamy prompt
LCALL WAIT_KEY ;Odczytujemy klawiaturę
ACALL WRITE_BCD ;Wyświetlamy akumulator w BCD
PUSH ACC ;w akumulatorze i w B pozostaje liczba w BCD
PUSH B ;Dwie operacje PUSH wysyłają liczbę BCD na stos
MOV A,#'D'
LCALL WRITE_DATA
MOV A,#'='
LCALL WRITE_DATA
;Od tego momentu konwertujemy liczbę BCD (setki w B, dziesiątki
;i jedności w A
POP A ;Pobieramy setki ze stosu
MOV B,#100
MULL AB ;Mnożymy setki przez 100
XCH A,B ;Przenosimy a A do B i odwrotnie
POP ACC ;Ściągamy ze stosu dziesiątki i jedności
PUSH B ;Na stos wysyłamy wynik mnożenia
;Do tego fragmentu możemy się ograniczyć jeżeli liczba BCD wykorzystuje
;tylko jeden bajt
MOV B,#16
DIV AB ;Dzielimy akumulator przez 16
PUSH B ;Resztę umieszczamy na stosie
MOV B,#10
MULL AB ;Akumulator mnożymy przez 10
POP B ;Zdejmujemy resztę ze stosu
ADD A,B ;Dodajemy B do A
;--------------------------------------------------------
POP B ;Zdejmujemy ze stosu pomnożone setki
ADD A,B ;Dodajemy pomnożone setki do reszty
LCALL WRITE_HEX ;Wyświetlamy HEX na wyświetlaczu
;Koniec procedury zamiany a BCD na HEX
PUSH ACC ;Wysyłamy liczbę na stos
MOV A,#'H'
LCALL WRITE_DATA
MOV A,#'='
LCALL WRITE_DATA
POP ACC
ACALL WRITE_BIN ;Wywoływany jest podprogram zamiany
;HEX na BIN i wyświetlenia go na LCD
PUSH ACC
MOV A,#'B'
LCALL WRITE_DATA
POP ACC
SJMP $
WRITE_BIN:
PUSH PSW
PUSH ACC ;Wysyłamy akumulator na stos
PUSH B ;Wysyłamy B na stos
ACALL DZIEL ;Wywoływany jest podprogram do konwersji
ACALL DZIEL ;liczby HEX na poszczególne bity
ACALL DZIEL ;liczby BIN
ACALL DZIEL
POP ACC ;Instrukcje do wyświetlania
LCALL WRITE_HEX ;liczby binarnej
POP ACC ;na wyświetlaczu
LCALL WRITE_HEX ;Kolejne instrukcje pobierają dane ze stosu
POP ACC ;umieszczone tam przez podprogramy
LCALL WRITE_HEX ;DZIEL, POP_00 i POP_10 i wyświetlają je
POP ACC ;na wyświetlaczu
LCALL WRITE_HEX
POP B ;Zdejmujemy ze stosu B
POP ACC ;Zdejmujemy ze stosu akumulator
POP PSW
RET ;Powrót z podprogramu
DZIEL:
MOV B,#2
DIV AB ;Dzielimy akumulator przez 2
XCH A,B ;Reszta z dzielenia do akumulatora a akumulator
;do B
JZ POP_00 ;Skok do POP_00 jeśli akumulator jest zerem
CLR ACC ;Zerujemy akumulator
SETB ACC.0 ;Po to by ustawić go na 01H
PUSH ACC ;Wysyłamy akumulator na stos
XCH A,B ;Odtwarzamy akumulator
MOV B,#2
DIV AB ;Dzielimy akumulator przez 2
XCH A,B ;Reszta z dzielenia do akumulatora a akumulator
;do B
JNZ POP_10 ;Skok to POP_10 jeśli akumulator nie jest zerem
XCH A,B ;Odtwarzamy akumulator
RET ;Wyjście z podprogramu
POP_00:
PUSH ACC ;Akumulator na stos
RET
POP_10:
POP ACC ;Odtwarzamy akumulator
SETB ACC.4 ;I ustawiamy go na 11H
PUSH ACC ;Wysyłamy akumulator na stos
RET ;Wyjście z podprogramu
WRITE_BCD:MOV B,#100 ;Podprogram zamienia liczbę
DIV AB ;w akumulatorze na BCD-
PUSH ACC ;setki w B, dziesiątki i jedności
MOV A,B ;w A a następnie wyświetla wynik
MOV B,#10 ;na wyświetlaczu
DIV AB
SWAP A
ORL A,B
POP B
XCH A,B
LCALL WRITE_HEX
MOV A,B
LCALL WRITE_HEX
RET ;Wyjście z podprogramu
2
6