Rozbudowane wyjaśnienie programu SMS32V50
Kliknij na dowolną linię kodu, aby rozwinąć szczegółowe wyjaśnienie działania i celu tej instrukcji.
1
; ==================================================
- Separator wizualny, który oddziela sekcje programu.
- Pomaga w orientacji w strukturze kodu.
2
; WYBÓR SYSTEMU LICZBOWEGO
- Komentarz opisujący, że poniższy fragment odpowiada za wybór systemu liczbowego przez użytkownika.
- System dziesiętny vs. binarny.
3
; ==================================================
- Kolejny separator wizualny – utrzymuje przejrzystość kodu.
4
- Pusta linia ułatwiająca czytelność kodu.
5
CLO ; Czyścimy pamięć programu
- CLO – instrukcja czyszczenia pamięci programu.
- Przygotowuje środowisko, usuwając poprzednie dane przed rozpoczęciem nowych operacji.
6
IN 00 ; Oczekiwanie na wybór użytkownika: '1' - system dziesiętny, reszta - binarny
- Odczyt danych z portu 00 – czeka na wejście od użytkownika.
- Interpretacja: jeśli naciśnięto '1', wybieramy system dziesiętny; w przeciwnym wypadku system binarny.
7
CMP AL, 31 ; Sprawdzamy, czy wciśnięto '1' (ASCII 31)
- Porównanie zawartości rejestru AL z wartością 0x31 (kod ASCII dla znaku '1').
- Umożliwia identyfikację wyboru użytkownika.
8
JZ system_dziesietny ; Jeśli tak, przechodzimy do systemu dziesiętnego
- JZ – skok, gdy wynik porównania wynosi zero (czyli warunek jest spełniony).
- Jeśli użytkownik wybrał '1', kontrola przechodzi do etykiety system_dziesietny.
9
MOV AL, 2 ; W przeciwnym razie ustawiamy system binarny
- Przypisanie wartości 2 do rejestru AL oznacza wybór systemu binarnego.
- Jest to domyślna opcja, jeśli użytkownik nie wprowadzi '1'.
10
MOV [BC], AL ; Zapisujemy wybór użytkownika w pamięci
- Przenosi wartość z AL do pamięci pod adresem wskazywanym przez rejestr BC.
- Dzięki temu późniejsze operacje wiedzą, jaki system liczbowy został wybrany.
11
JMP wprowadz_liczby ; Przechodzimy do etapu wprowadzania liczb
- Bezwarunkowy skok do etykiety wprowadz_liczby.
- Rozpoczyna proces wprowadzania danych przez użytkownika.
12
; ==================================================
- Separator – wizualnie oddziela sekcje kodu.
13
; SYSTEM DZIESIĘTNY
- Komentarz wskazujący, że poniższe instrukcje ustawiają system dziesiętny.
14
; ==================================================
- Kolejny separator sekcji.
15
- Pusta linia poprawiająca czytelność.
16
system_dziesietny:
- Etykieta system_dziesietny – punkt, do którego następuje skok, gdy wybrano system dziesiętny.
- W ten sposób kod rozgałęzia się zgodnie z wyborem użytkownika.
17
MOV AL, 10 ; Ustawiamy system dziesiętny
- Przypisuje wartość 10 do rejestru AL – reprezentuje system dziesiętny.
- Dzięki temu późniejsze operacje będą operować na systemie dziesiętnym.
18
MOV [BC], AL ; Zapisujemy wybór w pamięci
- Przechowuje wartość 10 w pamięci (adres BC), aby pozostałe operacje wiedziały, że system to dziesiętny.
19
JMP wprowadz_liczby ; Przechodzimy do wprowadzania liczb
- Skok do etykiety wprowadz_liczby – uruchamia etap pobierania liczb od użytkownika.
20
- Pusta linia dla wizualnego oddzielenia sekcji.
21
; ==================================================
- Separator – oddzielenie sekcji dotyczącej wprowadzania liczb.
22
; WPISYWANIE LICZB
- Komentarz – poniższe instrukcje odpowiadają za pobieranie cyfr od użytkownika.
- Pierwsza liczba, a potem druga – proces wprowadzania krok po kroku.
23
; ==================================================
24
- Pusta linia – poprawia czytelność.
25
wprowadz_liczby:
- Etykieta wprowadz_liczby – punkt wejścia do procedury wprowadzania cyfr.
- Pierwszy etap pobierania danych od użytkownika.
26
MOV CL, C1 ; Ustawiamy miejsce wyświetlania liczb
- Rejestr CL otrzymuje wartość etykiety C1.
- Określa on pozycję (adres) w pamięci, gdzie będą wyświetlane pierwsze cyfry.
27
MOV DL, CB ; Ustawiamy maksymalną liczbę cyfr na 10
- Rejestr DL otrzymuje wartość CB, która reprezentuje limit cyfr.
- Zapewnia to, że użytkownik nie wpisze więcej niż 10 cyfr.
28
- Pusta linia dla separacji wizualnej.
29
petla_wprowadzania:
- Etykieta petla_wprowadzania – początek pętli zbierającej kolejne cyfry.
- Pętla działa aż do naciśnięcia ENTER lub osiągnięcia limitu cyfr.
30
IN 00 ; Pobieramy cyfrę z klawiatury
- Instrukcja IN 00 odczytuje znak z portu 00.
- To tutaj użytkownik wprowadza kolejne cyfry.
31
CMP AL, 0D ; Sprawdzamy, czy wciśnięto ENTER (ASCII 0D)
- Porównanie rejestru AL z wartością 0x0D (ENTER).
- Jeśli wynik jest równy, oznacza to koniec wprowadzania bieżącej liczby.
32
JZ krok ; Jeśli tak, przechodzimy do obliczeń
- JZ – skok, gdy porównanie wykryje wartość 0 (ENTER).
- Przenosi sterowanie do etykiety krok – następny etap programu.
33
CMP CL, DL ; Sprawdzamy, czy liczba nie przekroczyła 10 cyfr
- Porównanie aktualnego wskaźnika CL z limitem cyfr zapisanym w DL.
- Zapobiega zapisaniu więcej niż 10 cyfr, co mogłoby uszkodzić pamięć.
34
JZ blad_przekroczenia ; Jeśli tak, zgłaszamy błąd
- Jeżeli CL osiąga wartość DL, następuje skok do procedury obsługi błędu.
- Zapewnia to bezpieczeństwo i kontrolę nad poprawnością danych wejściowych.
35
MOV [CL], AL ; Zapisujemy cyfrę w pamięci
- Instrukcja zapisuje wprowadzoną cyfrę z AL do pamięci pod adresem wskazywanym przez CL.
- Dzięki temu dane są tymczasowo przechowywane do dalszych obliczeń.
36
INC CL ; Przechodzimy do następnej cyfry
- Zwiększa wartość CL o 1, przygotowując miejsce na kolejną cyfrę.
- Umożliwia kolejne zapisy w pamięci.
37
JMP petla_wprowadzania ; Powtarzamy pętlę dla kolejnej cyfry
- Bezwarunkowy skok z powrotem do etykiety petla_wprowadzania.
- Pętla kontynuuje pobieranie danych aż do wciśnięcia ENTER lub przekroczenia limitu.
38
- Pusta linia oddzielająca fragmenty pętli.
39
; ==================================================
- Separator sekcji – przejście do następnego etapu programu.
40
; PRZEJŚCIE DO OBLICZEŃ
- Komentarz informujący, że następuje zmiana fazy działania programu.
- Teraz następuje przetwarzanie wcześniej wprowadzonych danych.
41
; ==================================================
- Kolejny separator wizualny.
42
- Pusta linia dla wyraźnego oddzielenia sekcji.
43
krok:
- Etykieta krok – punkt, w którym następuje sprawdzenie czy mamy dane do obliczeń.
- Przygotowuje system do przejścia między wprowadzaniem a obliczeniami.
44
CMP CL, CF ; Sprawdzamy, czy wpisano drugą liczbę
- Porównanie bieżącego wskaźnika CL z wartością CF, która wskazuje koniec pierwszej liczby.
- Umożliwia rozróżnienie między pierwszą a drugą liczbą.
45
JNS oblicz_wynik ; Jeśli tak, przechodzimy do obliczeń
- JNS – skok, jeśli wynik porównania jest nieujemny.
- Wskazuje, że druga liczba została już wpisana – możemy rozpocząć odejmowanie.
46
MOV CL, D1 ; Zmieniamy miejsce wpisywania na drugą linię
- Przypisuje do CL wartość etykiety D1.
- Ustawia nowy adres w pamięci, gdzie będzie zapisywana druga liczba.
47
MOV DL, DB ; Ograniczamy liczbę cyfr do 10
- Rejestr DL otrzymuje wartość DB, która stanowi limit dla drugiej liczby.
- Zapewnia spójność formatu obu wprowadzanych liczb.
48
JMP petla_wprowadzania ; Wracamy do wpisywania drugiej liczby
- Skok do pętli petla_wprowadzania – teraz już dla drugiej liczby.
- Pozwala na kontynuację wprowadzania kolejnych cyfr.
49
- Pusta linia oddzielająca etapy wprowadzania i obliczeń.
50
; ==================================================
- Separator – przejście do fazy obliczeń (odejmowania).
51
; OBLICZENIA (ODEJMOWANIE)
- Komentarz wskazujący, że poniższe instrukcje odpowiadają za operację odejmowania.
- Pierwsza liczba minus druga – krok po kroku.
52
; ==================================================
- Separator wizualny utrzymujący spójność układu.
53
- Pusta linia dla wyraźnego oddzielenia sekcji.
54
oblicz_wynik:
- Etykieta oblicz_wynik – punkt startowy procedury odejmowania wprowadzonych liczb.
- Początek głównej logiki obliczeniowej.
55
MOV DL, [BC] ; Pobieramy system liczbowy (2 lub 10)
- Odczytuje wartość systemu liczbowego (2 – binarny lub 10 – dziesiętny) z pamięci pod adresem BC.
- Wartość ta będzie używana przy korekcie wyniku (pożyczka) oraz przy konwersji wyników.
56
DEC CL ; Cofamy się do ostatniej cyfry
- Zmniejszenie wartości CL o 1 – przesuwa wskaźnik na ostatnią wprowadzoną cyfrę drugiej liczby.
- Przygotowuje adres dla operacji odejmowania.
57
- Pusta linia dla rozdzielenia logiki.
58
petla_obliczen:
- Etykieta petla_obliczen – pętla przetwarzająca pary cyfr do operacji odejmowania.
- Pętla będzie iteracyjnie odejmować cyfry parzysto ustawione w obu liczbach.
59
CMP CL, CF ; Sprawdzamy, czy zakończono obliczenia
- Porównanie bieżącego wskaźnika CL z wartością CF, która sygnalizuje koniec danych.
- Jeśli CL = CF, oznacza to, że nie ma już więcej par cyfr do przetworzenia.
60
JZ koniec_programu ; Jeśli tak, kończymy program
- Jeśli warunek z linii 59 jest spełniony, następuje skok do etykiety koniec_programu.
- Kończy to procedurę obliczeń.
61
MOV AL, [CL] ; Pobieramy cyfrę z drugiej liczby
- Wczytuje bieżącą cyfrę drugiej liczby do rejestru AL.
- Ta cyfra będzie odejmowana od odpowiadającej jej cyfry pierwszej liczby.
62
CMP AL, 20 ; Sprawdzamy, czy to spacja (ASCII 20)
- Porównanie wartości w AL z 0x20 (kod ASCII spacji).
- Sprawdza, czy osiągnięto separator między danymi – co sygnalizuje koniec drugiej liczby.
63
JZ koniec_programu ; Jeśli tak, kończymy program
- Skok do koniec_programu – gdy wykryta jest spacja, przetwarzanie zostaje zakończone.
- Zapobiega dalszemu przetwarzaniu pustych danych.
64
SUB CL, 10 ; Przechodzimy do pierwszej cyfry
- Odejmuje 10 od CL, co przesuwa wskaźnik do odpowiadającej pozycji w pierwszej liczbie.
- Pozwala to na uzyskanie pary cyfr do operacji odejmowania.
65
MOV BL, [CL] ; Pobieramy cyfrę z pierwszej liczby
- Wczytuje cyfrę pierwszej liczby do rejestru BL.
- Ta cyfra będzie bazą, od której odejmowana jest cyfra drugiej liczby.
66
ADD CL, 20 ; Przechodzimy do miejsca wyniku
- Dodaje 20 do CL, przesuwając wskaźnik do obszaru pamięci przeznaczonego na wynik operacji.
- Pozwala zapisać wynik w oddzielnym segmencie pamięci.
67
SUB BL, AL ; Odejmujemy drugą cyfrę od pierwszej
- Odejmuje wartość cyfry drugiej liczby (AL) od cyfry pierwszej (BL).
- Realizuje zasadę odejmowania "cyfra po cyfrze".
68
PUSH BL ; Zapisujemy wynik na stosie
- Przechowuje wynik odejmowania (BL) na stosie.
- Umożliwia tymczasowe zachowanie wyniku do dalszej obróbki.
69
POP AL ; Pobieramy wynik ze stosu
- Pobiera zapisany wcześniej wynik ze stosu i umieszcza go w rejestrze AL.
- Przygotowuje wartość do dalszej analizy (sprawdzenie znaku).
70
CMP AL, 0 ; Sprawdzamy, czy wynik jest ujemny
- Porównuje wynik odejmowania (AL) z zerem.
- Wykrywa, czy wynik operacji jest mniejszy od zera, co wskazuje na potrzebę pożyczki.
71
JS pozyczka ; Jeśli tak, przechodzimy do obsługi pożyczki
- JS – skok, jeśli wynik operacji jest ujemny (flaga znaku ustawiona).
- Przenosi kontrolę do etykiety pozyczka, gdzie następuje korekta wyniku.
72
JMP wypisz_wynik ; Jeśli nie, przechodzimy do wyświetlenia wyniku
- Jeśli wynik nie jest ujemny, następuje bezwarunkowy skok do etykiety wypisz_wynik.
- Rozpoczyna proces konwersji i wyświetlania wyniku.
74
; ==================================================
- Separator – oddziela sekcję obliczeniową od procedury pożyczki.
75
; OBSŁUGA POŻYCZKI
- Komentarz – poniższy blok odpowiada za korektę wyniku w przypadku ujemnego rezultatu.
- Mechanizm „pożyczki” umożliwia poprawne odejmowanie w systemie pozycyjnym.
76
; ==================================================
78
pozyczka:
- Etykieta pozyczka – punkt wejścia do procedury korekty wyniku.
- Tutaj wprowadzamy „pożyczkę” z wyższej pozycji w celu poprawienia ujemnego wyniku.
79
ADD AL, DL ; Dodajemy wartość systemu (2 lub 10), żeby poprawić wynik
- Dodaje wartość systemu liczbowego (przechowywaną w DL) do wyniku w AL.
- Korekta ta sprawia, że ujemny wynik staje się prawidłowy.
80
DEC CL ; Cofamy się do poprzedniej cyfry
- Zmniejsza CL, aby uzyskać adres poprzedniej cyfry, z której można „pożyczyć”.
- Pozwala na modyfikację wartości wyższej pozycji.
81
MOV BL, [CL] ; Pobieramy wartość
- Pobiera wartość poprzedniej cyfry do rejestru BL.
- Jest to cyfra, z której zostanie „pożyczone” jeden.
82
DEC BL ; Odejmujemy 1 (pożyczka)
- Zmniejsza wartość BL o 1 – realizuje mechanizm pożyczki.
- Obniża wartość cyfry z wyższej pozycji, aby wyrównać różnicę.
83
MOV [CL], BL ; Zapisujemy nową wartość
- Aktualizuje pamięć, zapisując zmodyfikowaną wartość BL pod adresem CL.
- Dzięki temu korekta jest trwale uwzględniona w dalszych obliczeniach.
84
ADD CL, 10 ; Wracamy do właściwej cyfry
- Przywraca wskaźnik CL do pierwotnej pozycji, aby kontynuować obliczenia.
- Pozwala wznowić iterację operacji odejmowania.
85
- Pusta linia oddzielająca sekcje.
86
; ==================================================
- Separator – wizualnie dzieli procedurę korekty od następnych operacji.
87
; SYGNALIZACJA BŁĘDU (PRZEKROCZENIE LIMITU CYFR)
- Komentarz – poniższe instrukcje aktywują sygnalizację błędu, gdy przekroczony zostanie limit cyfr.
- Zapobiega nieprawidłowej pracy programu przy błędnych danych wejściowych.
88
; ==================================================
90
blad_przekroczenia:
- Etykieta blad_przekroczenia – punkt wejścia przy wykryciu zbyt wielu cyfr.
- Przekierowuje program do procedury obsługi błędu.
91
MOV AL, 90 ; Przypisanie do AL wartości 90 (czerwone światło)
- Ustawia rejestr AL na 90 – symboliczna wartość sygnalizująca błąd.
- Wartość 90 może być interpretowana przez sprzęt jako komunikat o błędzie (np. czerwone światło).
92
OUT 01 ; Wyświetlenie czerwonego światła na wyjściu 01
- Wysyła wartość z AL do portu 01.
- Efektem jest wyświetlenie komunikatu o błędzie na dedykowanym wyjściu.
93
JMP koniec_programu ; Skok do zakończenia programu
- Bezwarunkowy skok do etykiety koniec_programu.
- Kończy działanie programu po wystąpieniu błędu.
95
; ==================================================
- Separator – oddziela sekcję błędu od wyświetlania wyniku.
96
; WYŚWIETLENIE WYNIKU
- Komentarz – poniższe instrukcje odpowiadają za konwersję i wyświetlenie końcowego wyniku.
- Wynik operacji odejmowania zostanie przekonwertowany na format ASCII.
97
; ==================================================
99
wypisz_wynik:
- Etykieta wypisz_wynik – punkt, w którym wynik odejmowania jest konwertowany i zapisywany.
- Początek procedury wyświetlania końcowego rezultatu.
100
ADD AL, 30 ; Konwersja wyniku na ASCII
- Dodaje 30 do wyniku w AL, co przekształca liczbę 0–9 w odpowiadający jej kod ASCII (np. 0 → 48, czyli '0').
- Pozwala na prawidłowe wyświetlenie cyfry na ekranie.
101
MOV [CL], AL ; Zapisujemy wynik w pamięci
- Zapisuje przekonwertowany wynik (w formacie ASCII) w pamięci pod adresem CL.
- Dzięki temu wynik jest widoczny w dedykowanym obszarze wyświetlania.
102
SUB CL, 11 ; Przechodzimy do kolejnej pary cyfr
- Zmniejsza wartość CL o 11, co przesuwa wskaźnik do miejsca, gdzie ma być zapisany wynik kolejnej operacji.
- Pozwala na iteracyjne przetwarzanie par cyfr z obu liczb.
103
JMP petla_obliczen ; Powtarzamy obliczenia dla następnej pary
- Bezwarunkowy skok z powrotem do etykiety petla_obliczen.
- Kontynuuje proces odejmowania dla kolejnych par cyfr.
104
- Pusta linia – oddzielenie końca procedury wyświetlania wyniku.
105
; ==================================================
- Separator – wyraźne zakończenie sekcji wyświetlania wyniku.
106
; KONIEC PROGRAMU
- Komentarz – informuje, że poniższe instrukcje kończą działanie programu.
107
; ==================================================
- Ostatni separator – wizualnie oddziela zakończenie kodu.
109
koniec_programu:
- Etykieta koniec_programu – oznacza zakończenie całego programu.
- Wszelkie operacje po tej etykiecie nie będą wykonywane.
110
END ; Zatrzymujemy program
- END – instrukcja kończąca wykonanie programu.
- Gwarantuje, że procesor zakończy pracę, a pamięć pozostanie niezmieniona.