   #Start Prev Next Contents

   Jak pisac programy w jezyku asembler?

Czesc 9 - Narzedzia programisty, czyli co moze nam pomagac w programowaniu
     _________________________________________________________________

Debugery

   (przeskocz debugery)

   Wszystkim sie moze zdarzyc, ze nieustanne, wielogodzinne gapienie sie
   w kod programu nic nie daje i program ciagle nie chce nam dzialac.
   Wtedy z pomoca przychodza debugery. W tej czesci zaprezentuje kilka
   wartych uwagi programow tego typu. Nie bede szczegolowo mowil, jak ich
   uzywac, bo zwykle posiadaja albo menu, albo dokumentacje czy inna
   pomoc.

   UWAGA: Niektore debugery moga wplywac na wartosci widziane w
   rejestrach. Moze sie tak stac na przyklad wtedy, gdy przerwanie, ktore
   wywolujemy, jest wewnetrznie wykorzystywane przez debuger. W
   szczegolnosci, moze to miec miejsce w przypadku Turbo Debuggera i
   funkcji 3Fh i 40h przerwania DOS-a (int 21h).

   Debuggery programow DOS-owych:
   (przeskocz DOSowe debugery)
    1. Watcom Debugger (WD).
       Rozpowszechniany z pakietem OpenWatcom, WD jest najlepszym z
       darmowych debugerow. Umozliwia wyswietlanie rejestrow procesora,
       flag, koprocesora, MMX i SSE, sledzenie wartosci zmiennych,
       stawianie pulapek (breakpoint, klawisz F9), podglad wyjscia
       programu (klawisz F4), wykonywanie do kursora i wiele innych
       dzialan. Posiada obsluge myszy. Pozwala debugowac wszystko, co
       moze byc wytworzone przez pakiet OpenWatcom - .com, .exe (MZ i LE)
       i wiele innych.
    2. Turbo Debugger (TD) firmy Borland.
       Jeden z najlepszych dostepnych. Niestety, nie darmowy. Umozliwia
       wyswietlanie rejestrow 16/32-bit, rejestrow koprocesora, stosu i
       pewnych regionow pamieci (standardowo DS:0000) oraz flag i daje
       mozliwosc modyfikacji ich wszystkich. Mozna obserwowac zmienne
       oraz to, co sie dzieje na ekranie poza debuggerem. Gdy testowalem
       program dzialajacy w trybie graficznym, to po kazdej komendzie
       monitor przelaczal sie w ten tryb, po czym wracal do debuggera, co
       umozliwia podgladanie naprawde kazdego kroku. Niestety, zrobienie
       czegokolwiek poza przejsciem do kolejnej instrukcji wymagalo
       przejscia w tryb pelnego ekranu, gdyz okienko w Windows nie za
       bardzo bylo potem odswiezane...
       Niestety, TD nie ma on pojecia o technologiach takich, jak MMX czy
       SSE (jest po prostu za stary). Posiada wiele opcji debugowania:
       trace-over, step-into, execute-to, animate, ...
       Nadaje sie do plikow .com/.exe (najnowsza wersja 5.5 obsluguje
       tylko pliki 32-bitowe). Mozna go sciagnac ze stron Borlanda po
       zarejestrowaniu sie.
    3. D86.
       Darmowy obsluguje tylko procesory 16-bitowe (brak rozszerzonych
       rejestrow), ale mozna podgladac rejestry, flagi, pamiec i
       koprocesor. D86 jest rozprowadzany razem z A86, darmowym
       kompilatorem jezyka asembler, i rozpoznaje symbole (nazwy
       zmiennych itp.), ktore A86 umieszcza w plikach .sym, co ulatwia
       proces debugowania.
       Posiada pelna dokumentacje. Pomoc w sprawie klawiszy jest w kazdej
       chwili dostepna pod kombinacja klawiszy Alt-F10.
       Niestety, mialem problem z przegladaniem aplikacji graficznej: po
       uruchomieniu trybu graficznego nie moglem wrocic do ekranu
       debuggera i musialem poczekac, az program sie zakonczy. D86 zna
       instrukcje koprocesora.
       Platna wersja, D386, zna MMX, SSE i 3DNow!.
    4. Codeview (CV) firmy Microsoft.
       Moje doswiadczenie z tym debuggerem jest krotkie, gdyz nie spelnil
       on wszystkich moich oczekiwan. Po uruchomieniu od razu trzeba
       otworzyc jakis program (i z tego co pamietam, aby otworzyc inny
       program, trzeba wyjsc z calego debuggera. Te programy, ktore
       chcialem otworzyc, CV otwieral tak dlugo, ze mozna bylo pomyslec,
       ze komputer sie zawiesil...
       Nawet chyba nie jest rozprowadzany osobno, tylko razem z MASMem
       (za darmo). Trzeba przejsc dlugi proces instalacji, ustawiac
       zmienne srodowiska, ...
    5. Insight
       Natrafilem na niego, gdy szukalem czegos (nowszego), co moglo by
       zastapic Turbo Debuggera. Wygladem nawet przypomina TD, ale ma
       kilka wad. Pierwsza jest brak rozpoznawania instrukcji koprocesora
       (wszystkie dekoduje jako ESC + cos tam). O MMX nie ma co myslec.
       Druga wada, ktora znalazlem jest to, ze po wejsciu w tryb
       graficzny okienko "Tryb MS-DOS" z debuggerem przestaje sie
       odswiezac i trzeba sie przelaczyc na pelny ekran.
       Ale jako-tako, dziala. Posiada opcje step-over, trace-into,
       animate. Mozna zmieniac wartosci rejestrow.
    6. Advanced Fullscreen Debugger
       Nawet ladne narzedzie. Pozwala w jednej chwili ogladac kod, stos,
       rejestry i 2 bloki pamieci (standardowo ustawiane na DS:0000).
       Obsluga jest prosta: na dole ekranu jest pokazane, co robia
       klawisze funkcyjne, ale mozna tez wpisywac komendy. Bardzo pomocne
       jest to, ze po wpisaniu pierwszej literki pojawiaja sie dostepne
       komendy zaczynajace sie od niej. Niestety, ma te dwa problemy,
       ktore ma Insight: po uruchomieniu trybu graficznego okienku z
       debuggerem przestaje byc odswiezane (trzeba sie przelaczyc na
       pelny ekran) i nie rozpoznaje instrukcji koprocesora.
    7. TRW2000
       Umie debugowac programy typu .com i .exe. Jednak cos jest nie tak
       z obsluga myszy a praca z nim nie jest zbyt wygodna. Strona domowa
       TRW: www.hktk.com/soft/soft_tools/trw_1.html

   Debuggery programow dla Windows:
   (przeskocz windowsowe debuggery)
    1. GoBug
       Czesc pakietu GoDevTools (www.godevtool.com). Poza nim sa m.in
       kompilator jezyka asembler oraz resource compiler. Wszystko to
       przydac sie moze przy pisaniu programow dla Windows. Ja osobiscie
       uzywam FASMa, ale moim debuggerem jest wlasnie GoBug. Ma mily dla
       oka wyglad, zna rejestry FPU, MMX. Wyswietla kod programu, stan
       rejestrow, oraz stos wzgledem ESP oraz EBP. Obsluguje
       wieloprocesowosc oraz symbole uzyte w kodzie, o ile znajdzie
       odpowiedni plik z nimi. Po przytrzymaniu prawego klawisza myszki
       na instrukcji pojawiaja sie bajty zapisane szesnastkowo, ktore sie
       na te instrukcje skladaja.
       GoBug rozpoznaje uruchomienia procedur Windows-owych z bibliotek
       DLL.
       Dobre narzedzie.
    2. Olly Debugger
       Mozna go za darmo sciagnac z jego strony domowej: ollydbg.de.
       Wyglada bardziej "profesjonalnie" niz GoBug i podobnie jak on,
       rozpoznaje uruchomienia procedur systemowych. Stos jest
       wyswietlany tylko wzgledem ESP. Wyswietla rejestry i flagi. Stara
       sie laczyc umieszczanie parametrow na stosie z uruchomieniem
       procedury, ale nie zawsze to wychodzi. Przewijajac okienko z kodem
       niektore instrukcje moga sie nagle zmieniac. Obsluga jest wedlug
       mnie trudniejsza. Czcionka instrukcji jest mniejsza, co jeszcze
       bardziej utrudnia ich rozczytanie. Bardziej nie wnikalem w jego
       obsluge.
       W tej chwili bardziej polecam GoBug niz OllyDbg.

   Wiem, ze nie wszyscy od razu z entuzjazmem rzuca sie do sciagania i
   testowania przedstawionych wyzej programow i do debugowania wlasnych.
   Niektorzy moga uwazac, ze debugger nie jest im potrzebny. Moze i tak
   byc, ale nie zawsze i nie u wszystkich. Czasem (zwykle po dlugim
   sterczeniu przed ekranem) przychodzi chec do uzycia czegos, co tak
   bardzo moze ulatwic nam wszystkim zycie.
   Pomyslcie, ze gdyby nie bylo debuggerow, znajdowanie bledow w
   programie musielibysmy pozostawic naszej nie zawsze wycwiczonej
   wyobrazni. Dlatego zachecam Was do korzystania z programow tego typu
   (tylko tych posiadanych legalnie, oczywiscie).
     _________________________________________________________________

Srodowiska programowania, edytory i disasemblery/hex-edytory

   (przeskocz ten dzial)

   Srodowisko programowania (Integrated Development Environment, IDE) to,
   jak wszyscy wiemy, program, ktory umozliwia edycje kodu, jego
   kompilacje i uruchamianie programu wynikowego. Znanych jest wiele IDE
   dla jezykow wysokiego poziomu, ale jezyk asembler tez ma kilka swoich:
   (przeskocz srodowiska)
     * RadASM - radasm.visualasembler.com - srodowisko programistyczne
       obslugujace wiele kompilatorow (MASM, TASM, NASM, HLA).
     * NasmIDE: uk.geocities.com/rob_anderton
     * TasmIDE: creamelana.tripod.com/Tasm/TasmIDE.htm
     * Srodowisko dla FASMa (wbudowane w kompilator w wersji GUI):
       flatasembler.net oraz Fresh: fresh.flatasembler.net
     * WinAsm Studio: code4u.net/winasm
     * AsmEdit: asmedit.massmind.org (dla MASMa)

   Jesli mimo tego ktos nie chce lub nie lubi uzywac IDE, zawsze moze
   skorzystac z ktoregos ze zwyklych edytorow. Przedstawione ponizej
   propozycje to co prawda nie musza byc edytorami napisanymi specjalnie
   do programowania w asemblerze, ale moze cos Wam przypadnie do gustu:
   (przeskocz edytory)
     * Programmer's File Editor: www.movsd.com/tools.htm
     * Quick Editor: www.movsd.com/qed.htm
     * The Gun: www.movsd.com/thegun.htm
     * HTE: hte.sf.net

   Jesli nie podoba sie Wam zaden z wymienionych, to mozecie wejsc na
   strone The Free Country.com - edytory, gdzie przedstawionych jest
   wiele edytorow dla programistow.

   Kolejna przydatna rzecza moze okazac sie disasembler lub hex-edytor.
   Jest to program, ktory podobnie jak debugger czyta plik i ewentualnie
   tlumaczy zawarte w nim bajty na instrukcje asemblera, jednak bez
   mozliwosci uruchomienia czytanego programu.
   Disasemblery moga byc przydatne w wielu sytuacjach, na przyklad gdy
   chcemy modyfikowac pojedyncze bajty po kompilacji programu, zobaczyc
   adresy zmiennych, itp.
   Oto kilka przykladow programow tego typu:
   (przeskocz hex-edytory)
     * XEdit: www.ircdb.org
     * b2hedit: www.movsd.com/tools.htm
     * Biew: biew.sf.net

   I ponownie, jesli nie spodoba sie Wam zaden z wymienionych, to mozecie
   wejsc na strone The Free Country.com - disasemblery, aby poszukac
   wsrod pokazanych tam programow czegos dla siebie.
     _________________________________________________________________

Programy typu MAKE

   Programy typu MAKE (na przyklad GNU MAKE) sluza do automatyzacji
   budowania duzych i malych projektow. Taki program dziala dosc prosto:
   uruchamiamy go, a on szuka pliku o nazwie "Makefile" w biezacym
   katalogu i wykonuje komendy w nim zawarte. Teraz zajmiemy sie
   omowieniem podstaw skladni pliku "Makefile".

   W pliku takim sa zadania do wykonania. Nazwa zadania zaczyna sie w
   pierwszej kolumnie, konczy dwukropkiem. Po dwukropku sa podane nazwy
   zadan (lub plikow) , od wykonania ktorych zalezy wykonanie tego
   zadania. W kolejnych wierszach sa komendy sluzace do wykonania danego
   zadania.
   UWAGA: komendy NIE MOGA zaczynac sie od pierwszej kolumny! Nalezy je
   pisac je po jednym tabulatorze (ale nie wolno zamiast tabulatora
   stawiac osmiu spacji).
   Aby wykonac dane zadanie, wydajemy komende make nazwa_zadania. Jesli
   nie podamy nazwy zadania (co jest czesto spotykane), wykonywane jest
   zadanie o nazwie "all" (wszystko).

   A teraz krotki przyklad:
   (przeskocz przyklad)
all:    kompilacja linkowanie
        echo "Wszystko zakonczone pomyslnie"

kompilacja:
        nasm -O999 -f obj -o plik1.obj plik1.asm
        nasm -O999 -f obj -o plik2.obj plik2.asm
        nasm -O999 -f obj -o plik3.obj plik3.asm

        tasm /z /m plik4.asm
        tasm /z /m plik5.asm
        tasm /z /m plik6.asm

linkowanie: plik1.obj plik2.obj plik3.obj plik4.obj plik5.obj plik6.obj
        alink -o wynik.exe plik1.obj plik2.obj plik3.obj plik4.obj \
                 plik5.obj plik6.obj -c- -oEXE -m-

help:
        echo "Wpisz make bez argumentow"

   Ale MAKE jest madrzejszy, niz moze sie to wydawac!
   Mianowicie, jesli stwierdzi, ze wynik.exe zostal stworzony POZNIEJ niz
   pliki .obj podane w linii zaleznosci, to nie wykona bloku
   "linkowanie", bo nie ma to sensu skoro program wynikowy i tak jest
   aktualny. MAKE robi tylko to, co trzeba. Oczywiscie, niezaleznie od
   "wieku" plikow .obj, dzial "kompilacja" i tak zostanie wykonany (bo
   nie ma zaleznosci, wiec MAKE nie bedzie sprawdzal wieku plikow).

   Znak odwrotnego ukosnika "\" powoduje zrozumienie, ze nastepna linia
   jest kontynuacja biezacej, znak krzyzyka "#" powoduje traktowanie
   reszty linijki jako komentarza.

   Jesli w czasie wykonywanie ktoregokolwiek z polecen w bloku wystapi
   blad (scisle mowiac, to gdy blad zwroci wykonywane polecenie, jak u
   nas TASM czy NASM), to MAKE natychmiast przerywa dzialanie z
   informacja o bledzie i nie wykona zadnych dalszych polecen
   (pamietajcie wiec o umieszczeniu w zmiennej srodowiskowej PATH sciezki
   do kompilatorow).

   W powyzszym pliku widac jeszcze jedno: zmiana nazwy ktoregos z plikow
   lub jakies opcji sprawi, ze trzeba ja bedzie zmieniac wielokrotnie, w
   wielu miejscach pliku. Bardzo niewygodne w utrzymaniu, prawda?
   Na szczescie z pomoca przychodza nam ... zmienne, ktore mozemy
   deklarowac w "Makefile" i ktore zrozumie program MAKE.
   Skladnia deklaracji zmiennej jest wyjatkowo prosta i wyglada tak:
                NAZWA_ZMIENNEJ = wartosc

   A uzycie:
                $(NAZWA_ZMIENNEJ)

   Polecam nazwy zmiennych pisac wielkimi literami w celu odroznienia ich
   od innych elementow. Pole wartosci zmiennej moze zawierac dowolny ciag
   znakow.

   Jesli chcemy, aby tresc polecenia NIE pojawiala sie na ekranie, do
   nazwy tego polecenia dopisujemy z przodu znak malpki "@", na przyklad
                @echo "Wszystko zakonczone pomyslnie"

   Uzbrojeni w te informacje, przepisujemy nasz wczesniejszy "Makefile":
   (przeskocz drugi przyklad)
# Moj pierwszy Makefile

NASM        = nasm     # ale mozna tu w przyszlosci wpisac pelna sciezke
NASM_OPCJE  = -O999 -f obj

TASM        = tasm
TASM_OPCJE  = /z /m

ALINK       = alink
ALINK_OPCJE = -c- -oEXE -m-

PLIKI_OBJ   = plik1.obj plik2.obj plik3.obj plik4.obj plik5.obj plik6.obj
PROGRAM     = wynik.exe

all:    kompilacja linkowanie
        @echo "Wszystko zakonczone pomyslnie"

kompilacja:
        $(NASM) $(NASM_OPCJE) -o plik1.obj plik1.asm
        $(NASM) $(NASM_OPCJE) -o plik2.obj plik2.asm
        $(NASM) $(NASM_OPCJE) -o plik3.obj plik3.asm

        $(TASM) $(TASM_OPCJE) plik4.asm
        $(TASM) $(TASM_OPCJE) plik5.asm
        $(TASM) $(TASM_OPCJE) plik6.asm

linkowanie:     $(PLIKI_OBJ)
        $(ALINK) -o $(PROGRAM) $(PLIKI_OBJ) $(ALINK_OPCJE)

help:
        @echo "Wpisz make bez argumentow"

   Oczywiscie, w koncowym "Makefile" nalezy napisac takie regulki, ktore
   pozwola na ewentualna kompilacje pojedynczych plikow, na przyklad
plik1.obj:      plik1.asm plik1.inc
        $(NASM) $(NASM_OPCJE) -o plik1.obj plik1.asm

   Choc na razie byc moze niepotrzebna, umiejetnosc pisania plikow
   "Makefile" moze sie przydac juz przy projektach zawierajacych tylko
   kilka modulow (bo nikt nigdy nie pamieta, ktore pliki sa aktualne, a
   ktore nie).
   O tym, ile "Makefile" moze zaoszczedzic czasu przekonalem sie sam,
   piszac swoja biblioteke - kiedys kompilowalem kazdy modul z osobna,
   teraz wydaje jedno jedyne polecenie make i wszystko sie samo robi.
   "Makefile" z biblioteki jest spakowany razem z nia i mozecie go sobie
   zobaczyc.

   Poprzednia czesc kursu (klawisz dostepu 3)
   Kolejna czesc kursu (klawisz dostepu 4)
   Spis tresci off-line (klawisz dostepu 1)
   Spis tresci on-line (klawisz dostepu 2)
   Ulatwienia dla niepelnosprawnych (klawisz dostepu 0)
