Logo podstrony Asembler
[Kurs dla poczatkujacych], [zawansowanych], [archiwum], i [linki].

Autorem jest Piotr Sokolowski


Uruchamianie programow w assemblerze(TASM)

Na poczatek wyjasnie znaczenie skrotu TASM - Turbo assembler
Pliki pisane w assemblerze moga miec wlasciwie dowolne rozszezenie, ale glownie nadaje sie je w
postaci *.asm. Pliki takie przygotowywuje sie w dowolnym edytorze tekstu(ja czesto stosuje EDIT
dosa lucz F4 nortona, jesli chcemy stworzyc w NC nowy plik to nacisnij SHIFT+F4 i wpisz nazwe
pliku). Gdy mamy gotowy plik *.asm to piszemy:
tasm nazwapliku.asm

wowczas otrzymujemy plik w przejsciowej postaci *.obj
Teraz piszemy:
tlink nazwapliku.obj

Teraz otrzymujemy gotowy plik nazwapliku.exe
Jesli mamy TASM 4.0 piszemy: ASM nazwapliku.asm
i bez zbednych zabaw otrzymujemy plik nazwapliku.exe




Ogolna skladnia assemblera(TASM) - PODSTAWY

Ponizej omowie ogolna skladnie turbo assemblera. Bede tu bazowal na przykladzie ktorego
celem bedzie wyswietlenie na ekranie rozkazem dosa(int 21h , ah = 09h ds:dx = adres tekstu
zakonczony na $) napis "czesc". Na poczatek stworzymy plik typu *.exe . Na poczatku pliku *.asm
umieszczamy dyrektywe assume po ktorej umieszczamy przypisanie danemu rejestrowi
segmentowemu nazwy segmentu ktora zadeklarujemy dalej - chodzi tu o rozdzielenie danych
i kodu. A wiec niech segment naszego kodu nazywa sie "code" a danych "dane" totez piszemy
assume cs:code,ds:dane
A wiec dalej deklarujemy segment danych:
dane segment
dane ends
Dyrektywa ends oznacza koniec segmentu a segment jego poczatek
Dalej trzeba umiescic w segmencie danych zmienna ktorej zawartosc wypiszemy:
dane segment
tekst db "Czesc$"
dane ends
Teraz definiujemy segment kodu wraz z odpowiednim kodem
code segment
start: ; etykieta informujaca o tym w ktorym miejscu zaczyna sie poczatek kodu
mov ax,seg dane
mov ds,ax ; inicjalizacja rejestru ds by wskazywal na nasze dane
mov ah,09h
mov dx,offset tekst
int 21h
mov ah,4Ch ; 4Ch rozkaz - zakoncz program
int 21h
code ends
end start ; end - dyrektywa informujaca o koncu kodu
Oto calkowita wersja:
assume cs:code,ds:dane
dane segment
tekst db "Czesc$"
dane ends
code segment
start: mov ax,seg dane
mov ds,ax
mov ah,09h
mov dx,offset tekst
int 21h
mov ah,04Ch
int 21h
code ends
end start
Teraz majac plik tekstowy *.asm dokonujemy jego normalnej kompilacji przez
TASM i TLINK poczym mozemy odpalic nasz gotoy plik *.exe.

Troche inaczej mozna zmodyfikowac nasz program by umiescic dane w segmencie
kodu i calkowicie pozbyc sie segmentu "dane". Totez w instrukcji assume
rejestr ds musi wskazywac na segment kodu a wiec ten w ktorym bedziemy
mieli umieszczone dane,czyli:
assume cs:code,ds:code
Teraz segment kodu bedzie wygladac tak ze na jego poczatku umieszcza sie dane
(przed etykieta start - logiczne bo ta czesc nie zostanie wykonana), dalej po tej
etykiecie umieszczamy kod z uwzlednieniem skopiowania zawartosci rejestru cs do ds
bowiem przeciez rejestr kodu(cs) bedzie jednoczesnie rejestrem danych(ds)
Gotowy taki program wyglada tak:
assume cs:code,ds:code
code segment
tekst db "Czesc$"
start:
mov ax,cs
mov ds,ax ; ds:=cs
mov ah,09h
mov dx,offset tekst
int 21h
mov ah,4Ch
int 21h
code ends
end start
Nalezy zeuwazyc, ze takie rozwiazanie ma sens w przypadku gdy dane i kod razem nie
przekrocza 64kb(wielkosc jednego segmentu).

Jesli chodzi o stworzenie pliku *.com to nalezy wiedziec, ze plik taki nie posiada zadnego naglowka
bowiem jest czystym kodem programu bez zadnych informacji o nim jak jest to w przypadku
pliku *.exe Cecha pliku *.com jest to, ze zawsze zaczyna sie od offsetu 100h(256h)
zwgledem swego segmentu kodu stad tez w kodzie naszego programu znajdzie sie dyrektywa:
org 100h
Natomiast dane dla odmiany umiescimy na koncu segmentu pod rozkazem zakonczenia programu
czyli 4Ch - wynika to z tad, ze ta czesc nigdy nie zostanie wykonana przez procesor. Stad
otrzymamy taki kod:
assume cs:code,ds:code
code segment
org 100h
start:
mov ax,cs
mov ds,ax
mov ah,09h
mov dx,offset tekst
int 21h
mov ah,4Ch
int 21h
tekst db "Czesc$"
code ends
end start
Nastepnie normalnie uzywamy polecenia TASM na naszym pliku z kodem, jednak kolejne
polecenie TLINK nalezy uzyc z parametrem "/t", co oznacza wygenerowanie pliku *.com
Mysle, ze powyzszy tekst troche ulatwil wam opanowanie podstaw assemblera.





Uzywanie assemblera w turbo pascalu

Turbo pascal udostepnia nam mozliwosc uzywania tzw. BASM czyli wbudowanego assemblera.
Juz na samym poczatku zaznacze, ze ma on spore ograniczenia bowiem normalnie udostepnia
rozkazy procesorow od 8086 do 8286. Instrukcje 286 wywoluje sie dyrektywa kompilatora
{G+} Do poinformowania kompilatora, ze bedziemy stosowac rozkazy BASM uzywa sie rozkazu
ASM ,a blok rozkazow BASM konczy sie rozkazem END;. NP:
Uses crt;
begin
asm
mov ax,13h
int 10h
end;
repeat
until keypressed;
end.
Powyzszy przyklad uruchamia tryb 13h(320x200 przy 256 kolorach).




Komunikacja BASM i pascala

Podstawowym zagadnienieniem BASM jest komunikacja BASM z samym turbo pascalem.
Czesto sie zdaza, ze w basm chcemy uzyc zmiennej pascala - wtedy pojawia sie problem.
Np. mamy zmienna "zmienna" typu word i chcemy nadac jej wartosc 5:
var
zmienna:word;
begin
asm
mov word ptr ds:[zmienna],5
end;
write(zmienna);
end.
Instrukcja mov przenosi tu wartosc "5" pod slowo("word") ktore znajduje sie w segmencie
danych("DS"- standardowy segment w ktorym pascal umieszcza dane), miedzy [] znajduje sie
nazwa zmiennej <- tu zostanie wstawiony jej offset czyli polozenie wzgledem poczatku
segmentu w ktorym sie znajduje czyli DS.
Rozwiazanie tego problemu przydaje sie przy wypisywaniu tekstu rozkazem 09h dosa.NP.
uses crt;
var
zmienna:string;
begin
clrscr;
zmienna:='Czesc$';
asm
mov ah,09h {ah = 09h -> wypisywanie tekstu ktorego poczatek jest DS:DX, zakonczonego znakiem $}
mov dx,offset zmienna+1 {dx = offset(zmienna)+1}
int 21h {wywolanie przerwania dosa -> 21h}
end;
end.

Tu mala uwaga!Rozkaz(a konkretnie "+1"):
mov dx,offset zmienna+1

Wynika z budowy zmiennej typu "string":
Bajt i jego znaczenie
0(jej offset + 0) Ilosc znakow w tym ciagu tekstowym
1(jej offset + 1) Pierwszy znak ciagu
Nalezy tez zauwazyc, ze nie musimy ustawiac wartosci DS na segment zmiennej "zmienna"
czyli segment danych, bo robi to standardowo pascal.

Copyright© 1999 Marcin Czesak. All right reserved