Kurs programowania w asemblerze
Szkielet programu
W asemblerze programy pisze się zazwyczaj według jednego, stałego szablonu, deklaruje się segmenty kodu, stosu i danych. Do deklaracji tych elementów używa się specjalnych dyrektyw:
- ASSUME rejestr segmentowy: nazwa segmentu [...] - informuje kompilator, z którego rejestru segmentowego ma korzystać przy odwołaniach do etykiety podanego segmentu, np:
ASSUME cs: CODE
ASSUME cs:NOTHING
Linijka pierwsza informuje kompilator, że CS zawiera numer segmentu kodu. Teraz jeśli będziemy odwoływać się do etykiety, będziemy odwoływać się do rejestru kodu CS.
W drugiej linijce anulujemy powiązanie z pierwszej linijki. - SEGMENT, ENDS - dyrektyw tych używa się do deklaracji segmentów. Sposób użycia:
nazwa_segmentu SEGMENT [typ_segmentu] [połączenie] ['klasa']
gdzie:
- nazwa_segmentu - jest to dowolna nazwa przyjmowana przez kompilator. Może być później w programie wykorzystywana jako identyfikator segmentu.
- typ_segmentu - określa sposób przydzielania pamięci:
- Byte - adres dowolny - segment ładowany jest w dowolnym miejscu
- Word - adres parzysty - segment ładowany jest na granicy pełnego słowa
- para - adres podzielny przez 16 - segment ładowany jest na granicy pełnego paragrafu
- Page - adres podzielny przez 256 - segment ładowany jest na granicy strony (1 strona=1024 bajty)
- połączenie - określa jak kompilator ma łączyć segmenty o tej samej nazwie
- Public - segmenty o tej samej nazwie łączone są w jeden ciągły segment. Wszystkie adresy w segmencie są łączone względem jego początku, np.:
DANE1 SEGMENT PUBLIC ZMIENNA1 DB 0 ZMIENNA2 DB 0 DANE1 ENDS DANE1 SEGMENT PUBLIC ZMIENNA3 DB 0 ZMIENNA4 DB 0 DANE1 ENDS ;zadeklarowanie tych dwóch segmentów jest równoważne DANE1 SEGMENT PUBLIC ZMIENNA1 DB 0 ZMIENNA2 DB 0 ZMIENNA3 DB 0 ZMIENNA4 DB 0 DANE1 ENDS
- stock - wszystkie segmenty o tej samej nazwie łączone są w jeden ciągły segment, który przy ładowaniu programu do pamięci inicjowany jest jako stos (SP pokazuje na ostatni bajt segmentu). Jeśli chce się definiować w programie segment stosu, trzeba zadeklarować dla niego parametr 'połączenie' - STACK. Jeśli zdefiniuje się stos bez parametru STACK, trzeba będzie samemu inicjować rejestry stosu.
- common - nakłada wszystkie segmenty o tej samej nazwie, umieszczając początek każdego w tym samym miejscu. Powstaje w efekcie obszar o wielkości największego z segmentów.
- memory - umieszcza wszystkie segmenty o tej samej nazwie w najwyższym fizycznym segmencie pamięci. Jeśli jest więcej niż jeden segment MEMORY nakładane są one jak w przypadku COMMON.
- AT adres - adresy wszystkich zmiennych i etykiet w segmencie są obliczane względem wartości segmentu podanej przy AT
- Public - segmenty o tej samej nazwie łączone są w jeden ciągły segment. Wszystkie adresy w segmencie są łączone względem jego początku, np.:
- klasa - określa kolejność segmentów
Przykładowy szablon programu w Asemblerze:
DSTACK
SEGMENT STACK 'STACK' ; deklaracjÄ… segmentu stosu
DB 64 DUP ('STACK') ; wypełnienie stosu
DSTACK ENDS ; koniec segmentu
ASSUME CS:CODE, SS:DSTACK
; przypisanie rejestrów do segmentów
CODE SEGMENT
Start:
<program>
CODE ENDS
DATA SEGMENT
<dane programu>
DATA ENDS
END Start
Autor: Karol Wierzchołowski, opracowano: 12.01.2002 r. Wszelkie prawa zastrzeżone.
