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 ; ==================================================
  • Separator wizualny.
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.
73  
  • Pusta linia.
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 ; ==================================================
  • Separator wizualny.
77  
  • Pusta linia.
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 ; ==================================================
  • Separator wizualny.
89  
  • Pusta linia.
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.
94  
  • Pusta linia.
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 ; ==================================================
  • Separator wizualny.
98  
  • Pusta linia.
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.
108  
  • Pusta linia.
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.