Skip to main content
  1. Zajęcia/
  2. Organizacja i Architektura systemów - 2025/

Skrypt

··
Table of Contents

Wstęp do Asemblera x86 16-bit
#

1. Czym jest asembler i architektura x86?
#

Asembler to język programowania niskiego poziomu, w którym każda instrukcja odpowiada niemal bezpośrednio jednej operacji procesora. Programujemy “blisko sprzętu”.

Architektura x86 to rodzina procesorów zapoczątkowana przez Intel 8086 (1978). Procesor 16-bitowy oznacza, że podstawowa jednostka danych to 16 bitów (2 bajty).

2. Tryby pracy procesora x86
#

Procesor x86 może działać w różnych trybach:

Real Mode (Tryb rzeczywisty)
#

  • Oryginalny tryb procesora 8086
  • Dostęp do maksymalnie 1 MB pamięci (20-bitowy adres)
  • Brak ochrony pamięci

Protected Mode (Tryb chroniony)
#

  • Wprowadzony w 80286
  • Pełna ochrona pamięci, wielozadaniowość
  • 32-bitowe adresy (dostęp do 4 GB RAM)

3. Segmentacja pamięci
#

Problem adresowania
#

Procesor 16-bitowy może operować na liczbach 0-65535 (FFFFh). Jak więc dostać się do 1 MB pamięci (adresy 0-1048575)?

Rozwiązanie: adresowanie segment:offset
#

Adres fizyczny = Segment × 16 + Offset

Segment:  1234h
Offset:   5678h
──────────────────
Fizyczny: 1234h × 10h + 5678h = 12340h + 5678h = 179B8h

Segmenty w procesorze
#

Procesor ma specjalne rejestry segmentowe:

  • CS (Code Segment) - kod programu
  • DS (Data Segment) - dane
  • SS (Stack Segment) - stos
  • ES (Extra Segment) - dodatkowy segment danych

Przykład dostępu do pamięci:

mov ax, ds:[0100h]  ; czytaj z DS:0100h
mov ax, es:[bx]     ; czytaj z ES:BX

4. Jak DOS uruchamia program?
#

Krok po kroku:
#

  1. Załadowanie do pamięci

    • DOS rezerwuje blok pamięci
    • Ładuje plik .EXE lub .COM
  2. Tworzenie PSP (Program Segment Prefix)

    • 256-bajtowy obszar przed programem
    • Zawiera informacje środowiskowe, linię komend (80h, 81h-FFh)
  3. Ustawienie rejestrów segmentowych

    • CS:IP wskazuje na punkt wejścia
    • DS i ES wskazują na PSP
    • SS:SP wskazuje na stos
  4. Przekazanie sterowania

    • Skok do programu (CS:IP)
  5. Po zakończeniu

    • Program wywołuje INT 21h, funkcja 4Ch
    • DOS zwalnia pamięć i przywraca kontrolę

5. Różnica między plikami COM i EXE
#

CechaCOMEXE
RozmiarMax 64 KB - 256 BPraktycznie nieograniczony
StrukturaProsty kod binarnyNagłówek + kod + dane
SegmentyWszystko w jednymOddzielne CS, DS, SS
Punkt wejściaZawsze 0100hOkreślony w nagłówku
RelokacjaNieTak (adresy poprawiane)
ŁatwośćProstszyBardziej elastyczny

EXE
#

  • Nagłówek EXE (MZ header) - 28 bajtów minimalnie:
    • Sygnatura “MZ” (4Dh 5Ah)
    • Rozmiar ostatniej strony
    • Liczba stron ( 512-bajtowych)
    • Liczba wpisów relokacyjnych
    • Rozmiar nagłówka w paragrafach
    • Minimalna/maksymalna pamięć dodatkowa
    • Początkowe wartości SS:SP i CS:IP
    • Offset tabeli relokacji
  • Tablica relokacji - lista adresów wymagających modyfikacji
  • Kod programu - segment CODE z instrukcjami
  • Dane programu - segment DATA z zainicjalizowanymi danymi
  • Segment stosu - STACK (jeśli zdefiniowany dyrektywą .stack)

Relokacja w EXE
#

Program EXE jest relokowalny, ponieważ:

  • Może być ładowany pod dowolny adres w pamięci
  • Zawiera tabelę relokacji z adresami, które trzeba poprawić
  • Przy ładowaniu, DOS:
    1. Wczytuje program do pamięci
    2. Odczytuje tabelę relokacji
    3. Dla każdego wpisu dodaje adres segmentu ładowania do wartości pod wskazanym adresem
    4. Ustawia CS:IP i SS:SP zgodnie z nagłówkiem

Jeśli kod zawiera MOV AX, SEG dane i program załadowano pod segment 1000h, DOS doda 1000h do wartości segmentu zapisanej w kodzie.

Brak relokacji w COM
#

Program COM jest nierelokowalny:

  • Jest zawsze ładowany pod stały adres 100h (w segmencie PSP)
  • Wszystkie adresy są obliczone na etapie kompilacji dla tego konkretnego offsetu
  • Nie ma nagłówka ani tabeli relokacji
  • Cały segment (CS=DS=ES=SS) wskazuje na ten sam obszar pamięci
  • Program jest po prostu “zrzutem pamięci” gotowym do wykonania

6. Dyrektywy asemblera MASM
#

Dyrektywy to instrukcje dla asemblera, nie dla procesora. Nie generują kodu maszynowego, tylko organizują program.

.model small
#

Określa model pamięci programu. Wpływa bezpośrednio na generowany kod maszynowy.

ModelKodDaneOpis
tiny64 KBrazem z kodemDla .COM
small64 KB64 KBStandardowy
medium>64 KB64 KBDuży kod
compact64 KB>64 KBDużo danych
large>64 KB>64 KBWszystko duże
huge>64 KB>64 KB (tablice >64KB)Największy

Rozmiar wskaźników i tryb adresowania
#

Model TINY/SMALL/COMPACT (near code):
#
CALL procedura

Generuje: E8 xx xx (3 bajty - relative near call)

  • Offset względny 16-bit
  • Zakłada, że procedura jest w tym samym segmencie kodu

Model MEDIUM/LARGE/HUGE (far code):
#

CALL procedura

Generuje: 9A xx xx yy yy (5 bajtów - absolute far call)

  • Pełny adres: offset (2 bajty) + segment (2 bajty)
  • Może wywołać procedurę w innym segmencie

.stack 512
#

Rezerwuje 512 bajtów na stos programu. Stos służy do:

  • Przechowywania adresów powrotu z funkcji
  • Zmiennych lokalnych
  • Tymczasowego przechowywania rejestrów

Można zmienić rozmiar, np. .stack 1024.

COM:
#
  • Dyrektywa jest IGNOROWANA
  • Program COM ma z góry ustalony stos na końcu dostępnej pamięci
  • Rejestr SP wskazuje na koniec segmentu (offset FFFEh lub FFFFh)
  • Stos “rośnie w dół” od końca dostępnych 64KB
  • Nie ma kontroli nad wielkością stosu w pliku COM
EXE:
#
  • Dyrektywa tworzy osobny segment stosu o wielkości XXX bajtów
  • Linker umieszcza ten segment w pliku wykonywalnym
  • Rejestry SS:SP są inicjalizowane przez loader systemu operacyjnego
  • SP wskazuje na koniec zaalokowanego obszaru stosu (offset XXX)
  • Rozmiar stosu można precyzyjnie kontrolować

.data
#

Początek sekcji zainicjalizowanych danych. Tu deklarujemy zmienne z wartościami początkowymi.

Deklaracja zmiennych
#

DyrektywaRozmiar
DB1 bajt
DW2 bajty (1 słowo)
DD4 bajty (2 słowa)
DF6 bajtów
DQ8 bajtów
DT10 bajtów

Przykłady:

Liczba  dw ?             ; 1 słowo, niezaincjalizowane
Liczby  dw 1, 2, 3, 2000
.data
    liczba dw 100
    tekst db "Hello$"
    tablica db 1, 2, 3, 4, 5

.data?
#

Sekcja niezainicjalizowanych danych (opcjonalna). Zmienne bez wartości początkowej.

.data?
    bufor db 100 dup(?)  ; 100 bajtów nieokreślonych

.code
#

Początek sekcji kodu programu.

.code
start:
    mov ax, @data    ; inicjalizacja DS
    mov ds, ax
    
    ; właściwy kod...
    
    mov ax, 4C00h    ; zakończenie
    int 21h
end start

end start - wskazuje punkt wejścia programu (etykietę start).

Szablon
#

.model small  
.stack 1024

.data
    ; {dane}

.code

main endp

    ; {kod}

main endp
end main

7. Rejestry procesora
#

Rejestry ogólnego przeznaczenia (General Purpose Registers)
#

Procesory x86 w trybie 16-bitowym dysponują czterema głównymi rejestrami ogólnego przeznaczenia, z których każdy może być używany jako jeden rejestr 16-bitowy lub dwa oddzielne rejestry 8-bitowe.

RejestrPełna nazwaPodział 8-bitowyTypowe zastosowanie
AXAccumulatorAH (high), AL (low)akumulator – operacje arytmetyczne, I/O, wynik funkcji
BXBaseBH, BLrejestr bazowy – adresowanie pamięci, wskaźnik tablic
CXCounterCH, CLlicznik – pętle, operacje stringowe, przesunięcia
DXDataDH, DLdane – I/O portów, mnożenie/dzielenie (starsze bity)

Uwagi:

  • Rejestry te można używać wymiennie w większości operacji arytmetycznych i logicznych
  • Podział na części wysoką (H - high) i niską (L - low) pozwala na efektywną pracę z danymi 8-bitowymi
  • Niektóre instrukcje wymagają konkretnego rejestru (np. mul używa AX, loop sprawdza CX)

Rejestry wskaźnikowe i indeksowe (Pointer and Index Registers)
#

RejestrPełna nazwaZastosowanie
SPStack Pointerwskaźnik wierzchołka stosu – adresuje bieżący element na stosie
BPBase Pointerwskaźnik bazowy ramki stosu – dostęp do parametrów i zmiennych lokalnych
SISource Indexindeks źródłowy – operacje stringowe, adresowanie tablic
DIDestination Indexindeks docelowy – operacje stringowe, adresowanie tablic

Uwagi:

  • SP automatycznie modyfikowany przez push, pop, call, ret
  • BP typowo używany do budowania ramek stosu w procedurach
  • SI i DI pracują razem w instrukcjach stringowych (movsb, cmpsb, etc.)
  • Rejestry te nie mają podziału na części 8-bitowe

Rejestry segmentowe (Segment Registers)
#

W architekturze x86 adres fizyczny jest tworzony z pary: rejestr segmentowy + offset. Każdy segment może mieć maksymalnie 64KB (0000h-FFFFh).

RejestrPełna nazwaZastosowanieDomyślny offset
CSCode Segmentsegment kodu – określa, gdzie znajduje się kod programuIP
DSData Segmentsegment danych – dostęp do zmiennych globalnychBX, SI, DI
SSStack Segmentsegment stosu – określa położenie stosuSP, BP
ESExtra Segmentdodatkowy segment – operacje stringowe, dodatkowe daneDI

Uwagi:

  • Adres fizyczny = Segment × 16 + Offset (np. CS:IP, DS:BX, SS:SP)
  • Rejestry segmentowe nie mogą być używane bezpośrednio w operacjach arytmetycznych
  • Zmiana CS możliwa tylko przez instrukcje skoku dalekiego (jmp far, call far, retf)
  • W małych modelach pamięci (.model small) często wszystkie segmenty wskazują na ten sam obszar

Rejestr wskaźnika instrukcji (Instruction Pointer)
#

RejestrPełna nazwaZastosowanie
IPInstruction Pointerwskaźnik następnej instrukcji do wykonania (w obrębie CS)

Uwagi:

  • Nie można bezpośrednio odczytać ani zapisać wartości IP
  • IP jest modyfikowany automatycznie przez procesor oraz instrukcje skoku i wywołań
  • Adres fizyczny następnej instrukcji: CS:IP
  • Do pośredniego dostępu można użyć call z natychmiastowym pop

Rejestr flag procesora (Flags Register)
#

Rejestr flag to specjalny 16-bitowy rejestr zawierający bity informacyjne o wyniku ostatniej operacji oraz kontrolujące tryb pracy procesora.

FlagaNazwaBitZnaczenieKiedy się ustawia (przykłady)
CFCarry Flag0przeniesienie/pożyczka przy operacjach bez znaku (unsigned)wynik dodawania przekracza 8/16 bitów; przy odejmowaniu pożyczka (np. sub ax,bx)
PFParity Flag2parzystość najmłodszego bajtu wynikujeśli najmłodszy bajt ma parzystą liczbę bitów = 1
AFAdjust Flag (Aux Carry)4przeniesienie/pożyczka między bitami 3 i 4 (BCD)używane głównie przy arytmetyce BCD (daa, das)
ZFZero Flag6wynik operacji = 0każda instrukcja arytmetyczna/logiczna, której wynik daje zero
SFSign Flag7znak wyniku – kopia najbardziej znaczącego bitu (MSB)wynik ma ustawiony bit najwyższego rzędu (wynik traktowany jako ujemny – signed)
TFTrap Flag8tryb krokowy (single-step)po ustawieniu powstaje przerwanie po każdej instrukcji (debugowanie)
IFInterrupt Flag9włączenie przerwań maskowalnychsti – włącza, cli – wyłącza przerwania maskowalne
DFDirection Flag10kierunek operacji stringowych0 = inkrementacja (domyślnie), 1 = dekrementacja (std ustawia, cld czyści)
OFOverflow Flag11przepełnienie dla wartości ze znakiem (signed)wynik arytmetyczny wykracza poza zakres signed (np. +32767 + 1 → -32768)

Uwagi:

  • Flagi CF, PF, AF, ZF, SF, OF – flagi stanu (modyfikowane przez operacje arytmetyczne/logiczne)
  • Flagi TF, IF, DF – flagi kontrolne (kontrolują tryb pracy procesora)
  • Dostęp do rejestru flag: pushf (odłóż na stos), popf (zdejmij ze stosu)
  • Instrukcje warunkowe (jz, jc, jg, etc.) sprawdzają kombinacje flag
  • Bity 1, 3, 5, 12-15 są zarezerwowane (zawsze = 0 w 8086/80286)

8. Podstawowe instrukcje asemblera
#

Przesyłanie danych
#

InstrukcjaOpisPrzykład
MOV dest, srcKopiuj src - destmov ax, 5
XCHG a, bZamień miejscamixchg ax, bx
LEA reg, memZaładuj adreslea dx, tekst

Uwaga: Nie można wykonać mov mem, mem - tylko przez rejestr!

Ustawianie rejestrów:

mov ah, 02h    ; do AH ładowana jest liczba 02h
mov dl, 07h    ; do DL ładowana jest liczba 07h

Arytmetyka
#

InstrukcjaOpisFlagi
ADD dest, srcdest = dest + srcZF, CF, OF
SUB dest, srcdest = dest - srcZF, CF, OF
INC destdest = dest + 1ZF, OF
DEC destdest = dest - 1ZF, OF
MUL srcAX = AL × src (8-bit)
DX:AX = AX × src (16-bit)
CF, OF
DIV srcAL = AX ÷ src, AH = reszta (8-bit)
AX = DX:AX ÷ src, DX = reszta (16-bit)
-

Przykład:

mov al, 255
inc al        ; AL = 0, ZF = 1, CF = 1

Logika
#

InstrukcjaOpis
AND dest, srcIloczyn logiczny
OR dest, srcSuma logiczna
XOR dest, srcAlternatywa rozłączna (exclusive or)
NOT destNegacja bitowa
TEST a, bAND bez zapisywania (tylko flagi)

Przesunięcia
#

InstrukcjaOpis
SHL dest, countShift left (× 2)
SHR dest, countShift right (÷ 2)
ROL dest, countRotate left
ROR dest, countRotate right

Przykład:

mov cl, 3
shl ax, cl    ; AX = AX × 8

Porównania i skoki
#

Etykieta:

start:

Skok bezwarunkowy:

jmp etykieta

Instrukcje porównania

InstrukcjaOpis działaniaWpływ na flagi
CMP r/m, r/m/immodejmuje: lhs - rhs, ale nie zapisuje wynikuZF, SF, CF, OF, PF, AF ustawiane na podstawie wyniku odejmowania
TEST r/m, r/m/immAND bitowy, wynik nie jest zapisywanyZF, SF, PF; CF i OF zawsze = 0; AF nieokreślone
CMPTEST
Działaniewykonuje lhs - rhs (odejmowanie)wykonuje lhs AND rhs
Wynik zapisanynienie
Porównanie typówsigned i unsignedzależności bitowe, maski, sprawdzenia pojedynczych bitów
Typowe zastosowaniaporównania liczb, warunki >,<,=sprawdzanie bitów, flag, testowanie pojedynczych właściwości

Instrukcje skoku (warunkowe)

InstrukcjaWarunek (flagi)Znaczenie
JE / JZ aZF = 1równeop1 == op2
JNE / JNZ aZF = 0różneop1 != op2
JC aCF = 1carry = 1
JNC aCF = 0carry = 0
JS aSF = 1wynik ujemny (sign)
JNS aSF = 0wynik dodatni/zero
JO aOF = 1overflow
JNO aOF = 0brak overflow
JP / JPE aPF = 1parzystość
JNP / JPO aPF = 0nieparzystość

BEZ ZNAKU (unsigned)

InstrukcjaWarunekZnaczenie
JA a(CF = 0) AND (ZF = 0)większe (unsigned)op1 > op2
JAE / JNC aCF = 0większe lub równe (unsigned)op1 >= op2
JB / JC aCF = 1mniejsze (unsigned)op1 < op2
JBE a(CF = 1) OR (ZF = 1)mniejsze lub równe (unsigned)op1 <= op2

ZE ZNAKIEM (signed)

InstrukcjaWarunekZnaczenie
JG a(ZF = 0) AND (SF = OF)większe (signed)op1 > op2
JGE aSF = OFwiększe lub równe (signed)op1 >= op2
JL aSF ≠ OFmniejsze (signed)op1 < op2
JLE a(ZF = 1) OR (SF ≠ OF)mniejsze lub równe (signed)op1 <= op2

Pętle
#

InstrukcjaOpis
LOOP labelCX–, jeśli CX ≠ 0 skocz
mov cx, 10
petla:
    ; kod powtarzany 10 razy
    loop petla

Stos
#

InstrukcjaOpis
PUSH srcWłóż na stos
POP destZdejmij ze stosu
PUSHFWłóż flagi
POPFZdejmij flagi

Procedury
#

InstrukcjaOpis
CALL procWywołaj procedurę
RETPowrót z procedury

9. Czym jest przerwanie (interrupt)?
#

Przerwanie to mechanizm komunikacji między programem a systemem operacyjnym lub BIOS-em.

Jak to działa?
#

  1. Program umieszcza parametry w rejestrach
  2. Wywołuje instrukcję INT <numer>
  3. Procesor:
    • Zapisuje aktualny stan na stosie
    • Skacze do procedury obsługi przerwania
    • Po zakończeniu wraca do programu

Przykład: wyświetlenie znaku
#

mov ah, 02h      ; funkcja 02h - wypisz znak
mov dl, 'A'      ; znak do wyświetlenia
int 21h          ; wywołaj DOS

Tabela przykładowych funkcji przerwania DOS (INT 21h)
#

INT 21h to główne przerwanie DOS-u do obsługi I/O, plików i systemu.

Funkcja (AH)OpisParametry wejścioweWynik
01hCzytaj znak z echo-AL = znak
02hWypisz znakDL = znak-
08hCzytaj znak bez echo-AL = znak
09hWypisz stringDS:DX = adres (kończy $)-
0AhBuforowany inputDS:DX = bufor-
3ChUtwórz plikDS:DX = nazwa, CX = atrybutyAX = uchwyt / błąd
3DhOtwórz plikDS:DX = nazwa, AL = trybAX = uchwyt / błąd
3EhZamknij plikBX = uchwyt-
40hZapisz do plikuBX = uchwyt, DS:DX = dane, CX = długośćAX = zapisane bajty
3FhCzytaj z plikuBX = uchwyt, DS:DX = bufor, CX = długośćAX = przeczytane bajty
42hPrzesuń wskaźnikBX = uchwyt, CX:DX = pozycja, AL = trybDX:AX = nowa pozycja
4ChZakończ programAL = kod powrotu-

Tryb otwarcia pliku (funkcja 3Dh, rejestr AL):

  • 00h = tylko odczyt
  • 01h = tylko zapis
  • 02h = odczyt/zapis
mov ah, 02h
mov dl, 07h
int 21h

wywołuje funkcję 02h przerwania 21h, która wysyła znak 07h (BEL / dzwonek).

Tabela funkcji INT 10h dla trybu tekstowego
#

AHFunkcjaParametry wejścioweParametry wyjścioweOpis
00hSet Video ModeAL = tryb wideo
(03h = 80x25 tekst kolorowy)
-Ustawia tryb pracy karty graficznej
01hSet Cursor ShapeCH = linia początkowa
CL = linia końcowa
-Zmienia wygląd kursora (rozmiar, widoczność)
02hSet Cursor PositionBH = strona
DH = wiersz (0-24)
DL = kolumna (0-79)
-Ustawia pozycję kursora na ekranie
03hGet Cursor PositionBH = stronaCH = kształt początek
CL = kształt koniec
DH = wiersz
DL = kolumna
Odczytuje pozycję i kształt kursora
05hSelect Active PageAL = numer strony (0-7)-Przełącza aktywną stronę ekranu
06hScroll Window UpAL = liczba linii (0=wyczyść)
BH = atrybut
CH,CL = lewy górny róg
DH,DL = prawy dolny róg
-Przewija okno w górę lub czyści ekran
07hScroll Window DownAL = liczba linii
BH = atrybut
CH,CL = lewy górny róg
DH,DL = prawy dolny róg
-Przewija okno w dół
08hRead Character and AttributeBH = stronaAH = atrybut
AL = znak
Odczytuje znak i jego atrybut z pozycji kursora
09hWrite Character and AttributeAL = znak
BH = strona
BL = atrybut
CX = liczba powtórzeń
-Wyświetla znak z atrybutem (kursor się nie przesuwa)
0AhWrite Character OnlyAL = znak
BH = strona
CX = liczba powtórzeń
-Wyświetla znak bez zmiany atrybutu
0EhTeletype OutputAL = znak
BH = strona
BL = kolor (tryb graficzny)
-Wyświetla znak jak terminal (z obsługą \n, \r, \b)
0FhGet Video Mode-AH = liczba kolumn
AL = tryb wideo
BH = aktywna strona
Pobiera informacje o aktualnym trybie
13hWrite StringAL = tryb zapisu
BH = strona
BL = atrybut
CX = długość
DH,DL = pozycja
ES:BP = adres tekstu
-Wyświetla cały ciąg znaków

Kody atrybutów kolorów (dla BH/BL)
#

Format bajtu atrybutu: KBBBTTTT
#

  • K - miganie (1 bit)
  • BBB - kolor tła (3 bity)
  • TTTT - kolor tekstu (4 bity)

Kolory (0-15):
#

WartośćKolorWartośćKolor
0Czarny8Ciemnoszary
1Niebieski9Jasnoniebieski
2ZielonyAJasnozielony
3CyjanBJasny cyjan
4CzerwonyCJasnoczerwony
5MagentaDJasna magenta
6BrązowyEŻółty
7JasnoszaryFBiały

Przykłady użycia:
#

Przykład 1: Czyszczenie ekranu
#

mov ah, 06h      ; Scroll up
mov al, 0        ; Cały ekran
mov bh, 07h      ; Atrybut: białe na czarnym
mov cx, 0        ; Lewy górny (0,0)
mov dx, 184Fh    ; Prawy dolny (24,79)
int 10h

Przykład 2: Wyświetlanie kolorowego tekstu
#

mov ah, 02h      ; Ustaw kursor
mov bh, 0
mov dh, 10       ; Wiersz
mov dl, 20       ; Kolumna
int 10h

mov ah, 09h      ; Wyświetl znak z atrybutem
mov al, 'A'      ; Znak
mov bh, 0        ; Strona
mov bl, 1Eh      ; Żółty na niebieskim (tło=1, tekst=E)
mov cx, 5        ; Powtórz 5 razy
int 10h

Przykład 3: Wyświetlanie tekstu funkcją teletype
#

mov ah, 0Eh      ; Teletype
mov al, 'H'      ; Znak
mov bh, 0        ; Strona
int 10h          ; Wyświetl 'H'

mov al, 'i'
int 10h          ; Wyświetl 'i'

mov al, '!'
int 10h          ; Wyświetl '!'

Przykład 4: Ukrywanie kursora
#

mov ah, 01h      ; Set cursor shape
mov ch, 20h      ; Bit 5 = 1 ukrywa kursor
mov cl, 0
int 10h

Przykład 5: Wyświetlanie całego ciągu
#

.DATA
    tekst DB 'Hello World!'
    dlugosc EQU $-tekst

.CODE
    mov ah, 13h      ; Write string
    mov al, 1        ; Tryb 1: przesuwaj kursor, użyj BL
    mov bh, 0        ; Strona
    mov bl, 0Eh      ; Żółty na czarnym
    mov cx, dlugosc  ; Długość
    mov dh, 12       ; Wiersz
    mov dl, 35       ; Kolumna
    push ds
    pop es
    lea bp, tekst    ; ES:BP wskazuje na tekst
    int 10h

11. Wskazówki
#

  1. Zawsze inicjalizuj DS na początku programu:

    mov ax, @data
    mov ds, ax
  2. Zawsze kończ programem prawidłowo:

    mov ax, 4C00h
    int 21h
  3. Nie można kopiować pamięć-pamięć bezpośrednio:

    ; ŹLE:
    mov [zmienna1], [zmienna2]
    
    ; DOBRZE:
    mov ax, [zmienna2]
    mov [zmienna1], ax
  4. Rozmiary muszą się zgadzać:

    ; ŹLE:
    mov al, word ptr [zmienna]  ; AL to 8-bit, word to 16-bit
    
    ; DOBRZE:
    mov ax, word ptr [zmienna]
  5. String musi kończyć się znakiem $ dla funkcji 09h:

    tekst db "String musi kończyć się znakiem $"

Materiały dodatkowe - sporo staroci
#

Dokumentacja techniczna
#

Tutoriale i kursy online
#

Narzędzia i środowiska
#

Referencje online
#

Tryb graficzny (Mode 13h)
#

Przerwania DOS i BIOS
#

  • DOS API Reference - lista funkcji int 21h
  • BIOS Services Reference - funkcje int 10h, 16h, 13h
  • IBM PC BIOS Source Code - historyczny kod źródłowy

Społeczności i fora
#

Emulatowy i debugowanie
#

  • DOSBox-X - rozszerzona wersja DOSBox z lepszym debuggerem
  • QEMU - emulator z możliwością debugowania
  • Bochs - emulator x86 z wbudowanym debuggerem

Historie i ciekawostki
#

Related