BLOK 1: Podstawy I/O i operacje na danych
Informacje organizacyjne
Termin oddania: do 12.12.2025
Punktacja: 7 punktów
Opóźnienie: -3 punkty za każdy tydzień
1. Środowisko pracy
Kompilacja w DOSBox-X
| |
Skrypt cl automatycznie wykonuje:
tasm program.asm- kompilacja do .OBJtlink program.obj- linkowanie do .EXE- Wyświetla ewentualne błędy
Debugowanie - TurboDebugger
| |
Podstawowe komendy:
F7- Step Into (krok do instrukcji)F8- Step Over (pomiń CALL)F9- Run to cursorCtrl+F2- Reset programuAlt+V- View menu (rejestry, pamięć, stos)
Porównanie z Visual Studio
Na zajęciach pokażę jak ten sam kod C wygląda w asemblerze pod Windows (x64).
To pomoże zrozumieć koncepcje uniwersalne dla każdej architektury.
2. Instrukcje asemblera - podstawy
2.1. Struktura programu .EXE
Każdy program w asemblerze dla DOS musi mieć określoną strukturę:
| |
Wyjaśnienie:
.model small- określa, że kod i dane mieszczą się w 64KB każdy.stack 512- rezerwuje 512 bajtów na stos.data- sekcja dla zmiennych zainicjalizowanych.code- sekcja z instrukcjami programu@data- adres segmentu danych (generowany przez assembler)mov ax, 4C00h; int 21h- standardowe zakończenie programu DOS
2.2. Rejestry procesora - przypomnienie
Procesor 8086 ma następujące rejestry 16-bitowe, z których każdy można podzielić na dwie części 8-bitowe:
| Rejestr | Części 8-bit | Typowe użycie |
|---|---|---|
| AX | AH, AL | Akumulator - arytmetyka, I/O, funkcje DOS |
| BX | BH, BL | Baza - adresowanie pamięci |
| CX | CH, CL | Licznik - pętle, przesunięcia |
| DX | DH, DL | Dane - I/O, mnożenie/dzielenie |
Rejestry wskaźnikowe:
- SI - Source Index (indeks źródłowy)
- DI - Destination Index (indeks docelowy)
- BP - Base Pointer (wskaźnik bazy stosu)
- SP - Stack Pointer (wskaźnik stosu)
Rejestry segmentowe:
- CS - Code Segment (segment kodu)
- DS - Data Segment (segment danych)
- SS - Stack Segment (segment stosu)
- ES - Extra Segment (dodatkowy segment)
2.3. Przerwania DOS (INT 21h)
INT 21h to główne przerwanie DOS-u do obsługi wejścia/wyjścia.
Najważniejsze funkcje dla BLOKU 1:
| Funkcja (AH) | Opis | Parametry wejściowe | Wynik |
|---|---|---|---|
| 01h | Czytaj znak z echo | - | AL = znak |
| 02h | Wypisz znak | DL = znak | - |
| 09h | Wypisz string | DS:DX = adres (kończy $) | - |
Przykład użycia funkcji 02h:
| |
Przykład użycia funkcji 01h:
| |
Przykład użycia funkcji 09h:
| |
2.4. Podstawowe operacje arytmetyczne
| |
2.5. Porównania i skoki warunkowe
| |
2.6. Pętle
| |
2.7. Konwersja cyfr ASCII
Bardzo ważne dla zadań:
Gdy wczytujemy cyfrę z klawiatury (funkcja 01h), dostajemy jej kod ASCII, nie wartość liczbową!
| Cyfra | Kod ASCII (hex) | Kod ASCII (dec) |
|---|---|---|
| ‘0’ | 30h | 48 |
| ‘1’ | 31h | 49 |
| ‘2’ | 32h | 50 |
| … | … | … |
| ‘9’ | 39h | 57 |
Konwersja cyfra ASCII → wartość liczbowa:
| |
Konwersja wartość liczbowa → cyfra ASCII:
| |
Konwersja małe/wielkie litery:
| Litera | Kod ASCII (hex) | Różnica |
|---|---|---|
| ‘A’ | 41h | - |
| ‘a’ | 61h | 20h |
| ‘Z’ | 5Ah | - |
| ‘z’ | 7Ah | 20h |
| |
3. Przykłady: C vs Asembler
Przykład 1: Hello World
Kod C:
| |
Asembler x86-16 (TASM):
| |
Visual Studio (x64 - do demonstracji):
| |
Analiza różnic:
- DOS: Używamy przerwania INT 21h do komunikacji z systemem
- x64: Używamy wywołań funkcji biblioteki C (printf)
- DOS: String kończy się znakiem ‘$’
- C: String kończy się znakiem ‘\0’ (null terminator)
- DOS: Bezpośrednia komunikacja ze sprzętem przez BIOS/DOS
- Modern: Abstrakcja przez system operacyjny
Przykład 2: Wczytanie i wyświetlenie znaku
Kod C:
| |
Asembler (TASM):
| |
Analiza:
- W C używamy funkcji
scanfiprintf- wysokopoziomowa abstrakcja - W asemblerze bezpośrednio wywołujemy funkcje DOS przez INT 21h
- Musimy ręcznie zarządzać rejestrami (AL, BL, DL)
- Każda operacja I/O wymaga ustawienia odpowiedniej funkcji w AH
Przykład 3: Prosta arytmetyka
Kod C:
| |
Asembler (TASM) - wersja uproszczona:
| |
Analiza:
- C: Kompilator automatycznie przydziela zmienne
- Asembler: Musimy jawnie zadeklarować zmienne w sekcji .data
- C: Operacje arytmetyczne są abstrakcyjne
- Asembler: Bezpośrednie operacje na rejestrach procesora
- C: printf obsługuje formatowanie
- Asembler: Ręczna konwersja liczby na znak ASCII
Przykład 4: Pętla i wyświetlanie
Kod C:
| |
Asembler (TASM):
| |
Analiza:
- C: Pętla
forz jawnym licznikiem i warunkiem - Asembler: Instrukcja
LOOPużywa rejestru CX - Procesor automatycznie dekrementuje CX i sprawdza warunek
- W C nowa linia to
\n, w DOS to dwa znaki: CR (0Dh) + LF (0Ah)
4. Zadania do wykonania
Forma oddawania
Każde zadanie oddajemy jako:
- Kod źródłowy (.asm)
- Skompilowany program (.exe)
- Sprawozdanie (PDF lub MD) zawierające:
- Opis rozwiązania
- Wyjaśnienie kluczowych fragmentów kodu
- Zrzuty ekranu z działania programu
- Napotkane problemy i ich rozwiązania
Zadanie 1: Hello World
Treść zadania: Napisz program, który wyświetla na ekranie Twoje imię i nazwisko, a następnie kończy działanie.
Wymagania:
- Użyj funkcji DOS 09h (wyświetlanie stringa)
- String musi kończyć się znakiem ‘$’
- Program musi poprawnie zakończyć działanie (INT 21h, AH=4Ch)
Wskazówki:
| |
W sprawozdaniu opisz:
- Dlaczego string musi kończyć się znakiem ‘$’?
- Jaka jest rola instrukcji
lea dx, tekst? - Co oznacza kod
mov ax, 4C00h; int 21h?
Zadanie 2: Wczytaj i wyświetl znak
Treść zadania:
Napisz program, który w pętli wczytuje znaki z klawiatury i wyświetla je na ekranie.
Program ma pomijać wszystkie znaki oprócz cyfr (‘0’-‘9’).
Pętla kończy się po naciśnięciu klawisza ESC (kod 1Bh).
Wymagania:
- Użyj funkcji 01h (wczytaj znak z echo) lub 08h (bez echo)
- Sprawdź czy znak jest cyfrą (zakres ‘0’-‘9’)
- Jeśli tak - wyświetl go funkcją 02h
- Jeśli nie - pomiń i czytaj następny
- Zakończ po naciśnięciu ESC
Wskazówki:
| |
W sprawozdaniu wyjaśnij:
- Jaka jest różnica między funkcją 01h a 08h?
- Dlaczego używamy instrukcji
jbijazamiastjlijg? - Jaki kod ASCII ma klawisz ESC i dlaczego taki?
Zadanie 3: Suma dwóch liczb jednocyfrowych
Treść zadania: Napisz program, który:
- Wczytuje dwie cyfry z klawiatury (znaki ‘0’-‘9’)
- Oblicza ich sumę jako wartości liczbowe
- Wyświetla wynik jako literę (od A do R)
Przykład:
- Wejście: ‘3’ i ‘5’
- Suma wartości: 3 + 5 = 8
- Wynik: ‘H’ (ósma litera alfabetu)
Wymagania:
- Konwersja cyfr ASCII na wartości liczbowe
- Dodawanie wartości
- Konwersja wyniku na literę (0→‘A’, 1→‘B’, …, 8→‘I’)
- Zakładamy, że suma < 18 (wynik < ‘S’)
Wskazówki:
| |
W sprawozdaniu wyjaśnij:
- Dlaczego odejmujemy 30h od cyfry ASCII?
- Jaki kod ASCII ma litera ‘A’ i dlaczego to ważne?
- Co się stanie jeśli suma będzie >= 26? (opcjonalnie: jak obsłużyć?)
Zadanie 4: Konwersja małe/wielkie litery
Treść zadania: Napisz program, który:
- Wczytuje jeden znak z klawiatury
- Sprawdza czy to litera (mała lub wielka)
- Jeśli mała litera → zamienia na wielką
- Jeśli wielka litera → zamienia na małą
- Wyświetla przekonwertowany znak
Wymagania:
- Sprawdzenie zakresu ‘a’-‘z’ i ‘A’-‘Z’
- Konwersja przez dodanie/odjęcie 20h
- Wyświetlenie wyniku
Wskazówki:
| |
W sprawozdaniu wyjaśnij:
- Dlaczego różnica między małą a wielką literą to dokładnie 20h?
- Jaki bit jest odpowiedzialny za wielkość litery?
- Dlaczego
or al, 20hzamienia na małą, aand al, 0DFhna wielką? - Co program powinien zrobić jeśli wejście nie jest literą?
Zadanie 5: Wyświetlanie ciągu znaków w pętli
Treść zadania:
Napisz program, który wyświetla 10 razy znak ‘*’ w jednej linii,
używając pętli z rejestrem CX.
Wymagania:
- Użycie instrukcji LOOP
- Rejestr CX jako licznik
- Funkcja 02h do wyświetlania pojedynczego znaku
Wskazówki:
| |
W sprawozdaniu wyjaśnij:
- Jak działa instrukcja LOOP krok po kroku?
- Co się stanie jeśli CX będzie miało wartość 0 przed pętlą?
- Dlaczego używamy CX, a nie innego rejestru?
- Jak wyświetlić 100 razy znak ‘*’ używając tylko 16-bitowego CX?
5. Wskazówki ogólne
Dobre praktyki
Zawsze inicjalizuj segment danych
1 2mov ax, @data mov ds, axZawsze poprawnie kończ program
1 2mov ax, 4C00h ; Kod zakończenia 0 w AL int 21hUżywaj znaczących nazw etykiet
1 2 3 4 5 6 7; DOBRZE: wczytaj_znak: koniec_petli: ; ŹŹLE: etykieta1: x:Dodawaj komentarze
1 2mov ah, 01h ; Funkcja 01h - czytaj znak int 21h ; Wywołaj DOS, wynik w AL
Częste błędy
Zapomnienie o inicjalizacji DS
1 2 3 4 5 6 7 8 9 10 11; ŹŹLE: .code main proc lea dx, tekst ; DS nie wskazuje na @data! ; DOBRZE: .code main proc mov ax, @data mov ds, ax lea dx, tekstBrak znaku ‘$’ w stringu
1 2 3 4 5; ŹŹLE: tekst db 'Hello' ; Funkcja 09h nie wie gdzie koniec! ; DOBRZE: tekst db 'Hello$'Niepoprawne zakończenie programu
1 2 3 4 5 6; ŹŹLE: ret ; To nie jest DOS! ; DOBRZE: mov ax, 4C00h int 21hMylenie kodów ASCII z wartościami
1 2 3 4 5 6 7 8 9 10 11; ŹŹLE: mov ah, 01h int 21h ; AL = '5' = 35h add al, 3 ; AL = 38h = '8' (NIEPOPRAWNE!) ; DOBRZE: mov ah, 01h int 21h ; AL = '5' = 35h sub al, '0' ; AL = 5 (wartość liczbowa) add al, 3 ; AL = 8 add al, '0' ; AL = '8' = 38h (ASCII)Zapomnienie o destrukcyjnym charakterze instrukcji
1 2 3 4 5 6 7 8 9; ŹŹLE: mov al, znak1 add al, znak2 ; AL zawiera sumę mov dl, al ; ...ale AL już straciliśmy znak1! ; DOBRZE: mov al, znak1 mov bl, al ; Kopia na później add al, znak2
Przydatne kody ASCII
| Znak | Hex | Dec | Znaczenie |
|---|---|---|---|
| NUL | 00h | 0 | Null terminator (C) |
| BEL | 07h | 7 | Dzwonek |
| BS | 08h | 8 | Backspace |
| TAB | 09h | 9 | Tabulacja |
| LF | 0Ah | 10 | Line Feed (nowa linia) |
| CR | 0Dh | 13 | Carriage Return |
| ESC | 1Bh | 27 | Escape |
| SPACE | 20h | 32 | Spacja |
| ‘0’ | 30h | 48 | Cyfra zero |
| ‘9’ | 39h | 57 | Cyfra dziewięć |
| ‘A’ | 41h | 65 | Wielka litera A |
| ‘Z’ | 5Ah | 90 | Wielka litera Z |
| ‘a’ | 61h | 97 | Mała litera a |
| ‘z’ | 7Ah | 122 | Mała litera z |
Debugowanie w TurboDebugger
Co warto sprawdzić:
View → Registers - obserwuj zmiany rejestrów
- Czy AL zawiera poprawny kod ASCII?
- Czy CX się prawidłowo zmniejsza w pętli?
View → Dump - pamięć programu
- Czy twoje stringi są poprawnie zakończone ‘$’?
- Jak wyglądają dane w pamięci?
F7 (Step Into) - wykonuj program instrukcja po instrukcji
- Śledź jak zmieniają się rejestry
- Sprawdź czy skoki warunkowe działają jak należy
Breakpointy (F2) - zatrzymaj program w konkretnym miejscu
- Postaw breakpoint przed i po krytycznej operacji
- Sprawdź stan rejestrów
6. Kryteria oceny
Każde zadanie oceniane jest według:
| Kryterium | Punkty |
|---|---|
| Program działa poprawnie | 40% |
| Kod jest czytelny i skomentowany | 20% |
| Sprawozdanie - wyjaśnienia techniczne | 25% |
| Jakość dokumentacji | 15% |
Uwaga: Nawet jeśli program nie działa w 100%, możesz otrzymać punkty za:
- Prawidłowe podejście do problemu
- Poprawną strukturę programu
- Merytoryczne wyjaśnienia w sprawozdaniu
- Próby rozwiązania i dokumentację problemów
Liczy się proces uczenia się i zrozumienie architektury!
Co powinno być w sprawozdaniu:
- Opis problemu - co program ma robić
- Analiza techniczna:
- Jakie funkcje DOS użyłeś i dlaczego?
- Jakie rejestry są wykorzystywane?
- Jak działają kluczowe fragmenty kodu?
- Fragmenty kodu z komentarzami - najważniejsze sekcje
- Zrzuty ekranu - działający program
- Napotkane problemy - błędy i ich rozwiązania
- Wnioski - co się nauczyłeś?
7. Podsumowanie: Co powinniśmy wynieść z BLOKU 1
Po tym bloku powinieneś rozumieć:
Strukturę programu w asemblerze
- Dyrektywy .model, .stack, .data, .code
- Procedura główna main proc…endp
- Inicjalizacja segmentu danych
- Zakończenie programu
Podstawy komunikacji z systemem DOS
- Przerwanie INT 21h i jego funkcje
- Funkcja 01h - wczytaj znak
- Funkcja 02h - wypisz znak
- Funkcja 09h - wypisz string
- Funkcja 4Ch - zakończ program
Rejestry procesora i ich role
- AX jako akumulator
- DX do przekazywania adresów i znaków
- CX jako licznik pętli
- Różnica między częściami 8-bit (AH, AL) a całym 16-bit (AX)
Kody ASCII i konwersje
- Różnica między kodem ASCII a wartością liczbową
- Konwersja cyfra ASCII ↔ wartość (±30h)
- Konwersja małe ↔ wielkie litery (±20h)
- Znaczenie bitów w reprezentacji znaków
Podstawowe konstrukcje programistyczne
- Pętle z instrukcją LOOP
- Porównania z CMP
- Skoki warunkowe (JE, JNE, JB, JA)
- Proste operacje arytmetyczne (ADD, SUB, INC, DEC)
Myślenie “blisko sprzętu”
- Każda operacja to bezpośrednia instrukcja procesora
- Ręczne zarządzanie rejestrami
- Brak automatycznych konwersji typów
- Kontrola nad każdym bajtem i bitem
Pamiętaj: To nie jest tylko nauka składni - to zrozumienie jak komputer rzeczywiście działa!
Po opanowaniu BLOKU 1 będziesz gotowy na bardziej zaawansowane tematy:
- Tablice i łańcuchy (BLOK 2)
- Procedury i funkcje (BLOK 3)
- Operacje na plikach (BLOK 4)
8. Zasoby dodatkowe
Kody ASCII - kompletna tabela
| |
Przydatne wzory
Sprawdzenie czy cyfra:
| |
Sprawdzenie czy wielka litera:
| |
Sprawdzenie czy mała litera:
| |
Powodzenia!
Marcin Klimek
Architektura i Organizacja Systemów Komputerowych
WSB Nowy Sącz, 2025/2026