Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Autor artykułu: mgr Jerzy Wałaszek |
©2024 mgr Jerzy Wałaszek |
SPIS TREŚCI |
|
Podrozdziały |
Najprostszego programu dla PMC II nawet nie musisz pisać. Po uruchomieniu symulatora w okienku tekstu programu otrzymasz:
; Program dla PMC II ; Autor: ; Wersja: ; Data: START: END |
Oczywiście program ten nic nie robi. Po kompilacji i uruchomieniu program natychmiast się zatrzymuje z powodu instrukcji END.
Kolejny program również jest bardzo prosty. Umieszcza ona w rejestrze akumulatora liczbę 133.
START: LDA #133 ;umieść w akumulatorze 133 END ;zakończ program |
Gdy go skompilujemy i uruchomimy, to po zatrzymaniu powinniśmy zauważyć, iż akumulator zawiera wartość 133.
Akumulator | Licznik Rozkazów | Rejestr Instrukcji |
0000000010000101 : 0085 : 133 | 0002 : 2 | 0000 : END |
Zwróć uwagę, iż zawartość akumulatora jest prezentowana przez symulator PMC II na trzy sposoby:
- jako liczba binarna: | 0000000010000101 |
- jako liczba szesnastkowa: | 0085 |
- jako liczba dziesiętna: | 133 |
Dzięki temu rozwiązaniu możesz w prosty sposób interpretować zawartość akumulatora wg potrzeb.
Licznik rozkazów zatrzymał się na adresie 2. Adres ten zawiera instrukcję END, co widzimy w rejestrze instrukcji. To właśnie ta instrukcja zatrzymała dalsze wykonywanie programu.
Program umieszcza liczbę 125 w pierwszej komórce pamięci.
DANE: DAT 0 ;tutaj umieścimy liczbę 125 START: LDA #125 ;umieszczamy najpierw w akumulatorze liczbę 125 STA $DANE ;teraz zawartość akumulatora umieszczamy w komórce 1 END |
Zwróć uwagę, iż przed uruchomieniem programu komórka 1 (o etykiecie DANE) zawiera wartość 0. Wartość tę umieszcza tam dyrektywa DAT. Po wykonaniu programu w komórce tej powinna znaleźć się wartość 125, czyli to, co program tam umieścił.
Adr | Etykieta | Inst | Argument | Pamięć |
00 | INOUT: | |||
01 | DANE: | DAT | 125 | 007D 125 |
02 | START: | LDA | #125 | 147D 5245 |
03 | STA | $DANE | 2801 10241 | |
04 | END | 0000 0 |
Przesłanie danych ma na celu pobranie informacji przechowywanej w jednej komórce i umieszczenie jej w innej. Poniższy program przenosi dane z komórki DANE1 do DANE2:
DANE1: DAT 147 ;tę liczbę skopiujemy do komórki następnej DANE2: DAT 0 ;tutaj będzie skopiowana zawartość komórki poprzedniej START: LDA $DANE1 ;pobieramy zawartość pierwszej komórki STA $DANE2 ;i umieszczamy ją w drugiej komórce END |
Po zakończeniu programu w obu komórkach DANE1 i DANE2 mamy tę samą wartość 147.
Adr | Etykieta | Inst | Argument | Pamięć |
00 | INOUT: | |||
01 | DANE1: | DAT | 147 | 0093 147 |
02 | DANE2: | DAT | 147 | 0093 147 |
03 | START: | LDA | $DANE1 | 1801 6145 |
04 | STA | $DANE2 | 2802 10242 | |
05 | END | 0000 0 |
Operacja zamiany zawartości polega na przesłaniu danych pomiędzy komórkami, tak aby ich zawartości zostały nawzajem zamienione: w komórce pierwszej ma się znaleźć to co było w drugiej, a we drugiej to co było w pierwszej Operacja taka wymaga dodatkowej zmiennej pomocniczej, w której przechowujemy tymczasowo zawartość jednej z komórek. Zamiany dokonujemy w trzech krokach:
Poniższy program zamienia miejscami zawartości komórek DANE1 i DANE2:
DANE1: DAT 15 ;zawartości tych dwóch komórek zostaną DANE2: DAT 188 ;zamienione miejscami X: DAT 0 ;to jest zmienna pomocnicza START: LDA $DANE1 ;przesyłamy DANE1 do X STA $X LDA $DANE2 ;przesyłamy DANE2 do DANE1 STA $DANE1 LDA $X ;przesyłamy X do DANE1 STA $DANE2 END |
Po wykonaniu programu komórki DANE1 i DANE2 mają zamienioną zawartość.
Adr | Etykieta | Inst | Argument | Pamięć |
00 | INOUT: | |||
01 | DANE1: | DAT | 188 | 00BC 188 |
02 | DANE2: | DAT | 15 | 000F 15 |
03 | X: | DAT | 15 | 000F 15 |
04 | START: | LDA | $DANE1 | 1801 6145 |
05 | STA | $X | 2803 10243 | |
06 | LDA | $DANE2 | 1802 6146 | |
07 | STA | $DANE1 | 2801 10241 | |
08 | LDA | $X | 1803 6147 | |
09 | STA | $DANE2 | 2802 10242 | |
10 | END | 0000 0 |
PMC II posiada tylko jedno urządzenie wyjścia - rejestr INOUT, który zajmuje adres 0 w przestrzeni adresowej. Każdy zapis do tego rejestru powoduje przesłanie na wyświetlacz jednego znaku. Poniższy program wyświetla literkę A:
START: LDA #"A ;pobieramy do akumulatora kod literki A STA $INOUT ;przesyłamy go do rejestru wyjścia END |
Po wykonaniu tego programu na wyświetlaczu pojawi się literka A.
A |
Pętla to konstrukcja programowa, w której wybrana grupa instrukcji jest cyklicznie powtarzana. Pętla nieskończona wykonywana jest ciągle, bez końca. Aby zatrzymać program z pętlą nieskończoną musisz posłużyć się przyciskiem STOP. Poniższy program wyświetla ciąg zer i jedynek.
START: LDA #"0 ;pobieramy do akumulatora znak 0 STA $INOUT ;przesyłamy go na wyjście LDA #"1 ;pobieramy znak 1 STA $INOUT ;przesyłamy go na wyjście JMP #START ;skaczemy na początek programu - powtarzamy od nowa |
Cechą charakterystyczną pętli nieskończonej jest instrukcja skoku JMP do początku pętli. Skok ten powoduje ponowne wykonywanie rozkazów zawartych pomiędzy początkiem pętli a instrukcją skoku.
1010101010101010101010101010101010101010101010101010101010101010 |
Cechą odróżniającą komputery od prostych liczydeł jest możliwość podejmowania różnych działań w zależności od sytuacji napotkanej w trakcie obliczeń. Obliczenia niejako mogą być wykonywane różnymi drogami w zależności od wyników operacji poprzednich. Dzięki tym cechom komputer może działać celowo - mądrze, inteligentnie.
W repertuarze rozkazów PMC II mamy dwie instrukcje, których wykonanie zależy od spełnienia pewnego warunku:
JZR - skok do adresu, gdy akumulator zawiera zero
JMI - skok
do adresu, gdy akumulator zawiera wartość ujemną
Wbrew pierwszemu wrażeniu te dwie instrukcje pozwalają badać nawet złożone warunki. Poniżej podajemy odpowiednie przykłady:
Poniższy program bada liczbę przechowywaną w zmiennej DANE. W zależności od wartości tej liczby wyświetla jeden z napisów <0, =0 lub >0.
DANE: DAT -256 START: LDA $DANE ;pobieramy liczbę do akumulatora JZR #ZERO ;czy liczba równa zero? JMI #MINUS ;czy liczba ujemna? LDA #"> ;liczba dodatnia JMP #PISZ ;wyświetlamy tekst ZERO: LDA #"= ;liczba równa zero JMP #PISZ MINUS: LDA #"< ;liczba ujemna PISZ: STA $INOUT ;wypisujemy odpowiedni tekst LDA #"0 STA $INOUT END |
Poniższy program bada zawartość komórki DANE. Jeśli jest ona ujemna, to zmienia ją na dodatnią.
DANE: DAT -68 ;komórka z danymi START: LDA $DANE ;sprawdzamy, czy liczba jest ujemna JMI #MINUS ;jeśli tak, skaczemy do etykiety MINUS END ;jeśli nie, kończymy program. Liczba jest dodatnia MINUS: LDA #0 ;zmieniamy znak liczby odejmując ją od 0 SUB $DANE STA $DANE END |
Ten program bada zawartość dwóch komórek DANE1 i DANE2. W komórce MAX umieszcza większą z nich.
DANE1: DAT 139 ;komórki z danymi DANE2: DAT 278 MAX: DAT 0 ;tutaj program umieści większą z liczb START: LDA $DANE1 ;pobieramy pierwszą liczbę SUB $DANE2 ;testowo odejmujemy od niej drugą liczbę JMI #D2 ;jeśli różnica mniejsza od 0, to DANE2 jest większa LDA $DANE1 ;tutaj większa jest DANE1 JMP #KONIEC D2: LDA $DANE2 ;tutaj większa jest DANE2 KONIEC: STA $MAX ;w MAX umieszczamy większą z liczb END |
Poniższy program odczytuje dane z wejścia PMC II. Jeśli bufor jest pusty, to odczyt rejestru daje wartość 0. W takim przypadku program czeka aż na wejściu pojawi się jakaś dane. To jest pierwsza pętla warunkowa - cykliczny odczyt wejścia aż pojawi się na nim dana.
Gdy na wejściu pojawią się dane program wchodzi w drugą pętle warunkową - odczytuje dane i przesyła je na wyjście aż skończą się. W takim przypadku program jest kończony.
START: LDA $INOUT ;pobieramy znak z wejścia JZR #START ;jeśli brak znaku, czekamy aż się pojawi PISZ: STA $INOUT ;odczytany znak przesyłamy na wyjście LDA $INOUT ;pobieramy kolejny znak JZR #KONIEC ;jeśli dane się skończyły, kończymy JMP #PISZ ;w przeciwnym razie kontynuujemy KONIEC: END |
Kolejny program wykorzystuje pośredni tryb adresowania do przesłania zadanego tekstu na wyjście. Tekst jest przesyłany z kolejnych komórek pamięci dotąd, aż zostanie napotkany znak o kodzie 0. Wtedy program kończy swoje działanie.
TEKST: DAT "W ;w kolejnych komórkach umieszczamy DAT "I ;poszczególne literki tekstu witaj DAT "T DAT "A DAT "J DAT 0 ;to jest koniec tekstu TPTR: DAT TEKST ;tutaj mamy adres pierwszego znaku tekstu START: LDA *TPTR ;pobieramy znak tekstu JZR #KONIEC ;jeśli koniec tekstu, kończymy STA $INOUT ;znak przesyłamy na wyjście INC $TPTR ;zwiększamy adres tekstu - następny znak JMP #START ;kontynuujemy pętle z następnym znakiem KONIEC: END |
Poniższy program wyświetla zadaną ilość literek X.
LICZNIK: DAT 15 ;liczba obiegów pętli START: LDA $LICZNIK ;sprawdzamy, czy licznik osiągnął 0 JZR #KONIEC ;jeśli tak, kończymy SUB #1 ;zmniejszamy licznik o 1 STA $LICZNIK LDA #"X ;na wyjście przesyłamy znak X STA $INOUT JMP #START ;kontynuujemy pętlę KONIEC: END |
Drugi program wypisuje na wyświetlaczu wszystkie duże literki od A do Z.
LICZNIK: DAT "A ;wartość początkowa licznika - kod literki A START: LDA $LICZNIK ;licznik przesyłamy na wyjście STA $INOUT SUB #"Z ;sprawdzamy, czy licznik osiągnął wartość Z JZR #KONIEC ;jeśli tak, kończymy INC $LICZNIK ;jeśli nie, przechodzimy do kolejnej literki JMP #START ;i kontynuujemy pętlę KONIEC: END |
Kolejne od końca cyfry otrzymujemy jako resztę z dzielenia liczby przez podstawę systemu, w którym chcemy zapisać liczbę. Wartość liczby dzielimy przez podstawę. Operację kontynuujemy dotąd, aż liczba osiągnie wartość 0. Wtedy otrzymane cyfry wyświetlamy. Dokładne algorytmy zamiany liczb na ciągi znaków znajdziesz w artykule Binarne Kodowanie Liczb.
Poniższy program wyświetla dziesiętnie zawartość komórki DANE.
DANE: DAT 26541 ;liczba do wyświetlenia - dodatnia! CYFRY: DAT 0 ;bufor na 5 cyfr DAT 0 DAT 0 DAT 0 DAT 0 CPTR: DAT 0 ;wskaźnik cyfr w buforze START: LDA #CYFRY ;ustawiamy CPTR na ostatnią cyfrę ADD #4 STA $CPTR ;CPTR -> CYFRY[4] LP1: LDA $DANE ;pobieramy liczbę MOD #10 ;wyznaczamy cyfrę ADD #48 ;dodajemy kod ASCII STA *CPTR ;wstawiamy cyfrę do bufora LDA $CPTR ;przesuwamy się na kolejną cyfrę SUB #1 STA $CPTR LDA $DANE ;liczbę dzielimy przez podstawę 10 DIV #10 STA $DANE JZR #PISZ ;jeśli koniec, wypisujemy bufor JMP #LP1 ;jeśli nie, kontynuujemy pętlę PISZ: INC $CPTR ;CPTR wskazuje o jedną cyfrę wcześniej. Korygujemy LDA *CPTR ;pobieramy cyfrę STA $INOUT ;przesyłamy ją na wyjście LDA $CPTR ;sprawdzamy, czy koniec bufora SUB #CYFRY SUB #4 JZR #KONIEC JMP #PISZ ;jeśli nie, kontynuujemy KONIEC: END |
Dokładne algorytmy odczytu liczb w dowolnym systemie pozycyjnym znajdziesz w artykule Binarne Kodowanie Liczb.
Poniższy program odczytuje z wejścia liczbę (musi być zapisana poprawnie) w postaci ciągu znaków i wyznacza jej wartość w komórce DANE. Tam też zobaczymy wynik po zakończeniu programu.
DANE: DAT 0 ;tutaj znajdzie się odczytana z wejścia liczba X: DAT 0 ;zmienna pomocnicza START: LDA $INOUT ;czekamy, aż na wejściu pojawią się znaki JZR #START LP1: SUB #48 ;odejmujemy kod ASCII STA $X ;cyfrę umieszczamy w zmiennej pomocniczej LDA $DANE ;liczbę mnożymy przez 10 MUL #10 ADD $X ;dodajemy cyfrę STA $DANE LDA $INOUT ;pobieramy kolejną cyfrę JZR #KONIEC ;jeśli koniec cyfr, kończymy JMP #LP1 ;w przeciwnym razie kontynuujemy KONIEC: END |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.