
|
Autorem jest Piotr Sokolowski 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 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. 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 |