assembly howto pl 3 MURXXH7UQ6NJ6OJLDCHDDT2IQFFIOVPDDWMXA7Q


Assembly HOWTO: ASSEMBLERY Następna strona Poprzednia strona Spis treści 3. ASSEMBLERY 3.1 Inline Assemblera GCC Dobrze znany kompilator GNU C/C++ (GCC), zoptymalizowany 32-bitowy kompilator będący sercem projektu GNU, wspiera całkiem dobrze architekturę x86, włączając w to zdolność wstawiania kodu assemblera w programach w C, w sposób gdzie zarządzanie rejestrami może być wyspecyfikowane lub pozostawione GCC. GCC działa na większości dostępnych platform, dla godnych uwagi Linux-a, *BSD, VST, OS/2, *DOS-a, WIN*, itd. Gdzie znaleźć GCC Orginalny adres GCC jest adresem FTP GNU ftp://prep.ai.mit.edu/pub/gnu/ razem ze wszystkimi wersjami aplikacji z projektu GNU. Przekompilowane i skonfigurowane dla Linux-a wersje są w ftp://sunsite.unc.edu/pub/Linux/GCC/ Istnieje wiele kopii FTP obu adresów, na całym świecie a także na nośnikach CD. Rozwój GCC został podzielony niedawno na dwie części. Więcej na temat eksperymentalnej wersji egcs mozna znaleźć na http://www.cygnus.com/egcs/Źródła przystosowane do twojej ulubionego OS, oraz przekompilowane binaria można znaleźć na zwykłych adresach FTP. Najbardziej popularny port GCC dla DOS-a nosi nazwę DJGPP i może być znaleziony w katalogach o takiej nazwie na adresach FTP. Zobacz: http://www.delorie.com/djgpp/Jest także port GCC na OS/2 nazwany EMX, działający także pod DOS-em, zawierający wiele bibliotek emulujących wywołania funkcji unix-a. Zobacz: http://www.leo.org/pub/comp/os/os2/gnu/emx+gcc/ http://warp.eecs.berkeley.edu/os2/software/shareware/emx.html ftp://ftp-os2.cdrom.com/pub/os2/emx09c/ Gdzie znaleźć dokumentacje GCC Inline Asm Dokumentacja GCC zawiera pliki w formacie texinfo. Możesz przekompilować je TeX-em i wydrukować rezultat, lub przekonwertować je do .info i oglądać emacs-em, lub przekonwertować je do .html. Możesz przekonwertować je (właściwymi narzędziami) do tego co lubisz najbardziej, lub czytać takie jakie są. Pliki .info są ogólnie dostarczane z każdą dobrą instalacją GCC. Właściwą sekcją do sprawdzenia jest: C Extensions::Extended Asm:: Sekcja Invoking GCC::Submodel Options::i386 Options:: może być ci także pomocna. W szczególności, podaje ci specyficzne ograniczenia nazw rejestrów: abcdSDB korespondują do %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp wyłączając (nie ma litery dla %esp). Zasoby gier dla DJGPP (nie tylko dla hackerów gier) mają swoją stronę specjalnie o assemblerze: http://www.rt66.com/~brennan/djgpp/djgpp_asm.htmlJest jeszcze strona www nazwana ``DJGPP Quick ASM Programming Guide'', zawierająca od URL-i do FAQ, AT&T Składnia ASM x86 , Pewne informacje o inline ASM, i konwertowanie plików .obj/.lib: http://remus.rutgers.edu/~avly/djasm.htmlGCC zależy od GAS podczas assemblacji, i śledzi jego składnię (patrz poniżej); pamiętając że inline asm wymaga znaków procent podczas cytowania by mogły przejść do GAS. Zobacz poniższą sekcję o GAS. Znajdziesz pełno użytecznych przykładów w podkatalogu linux/include/asm-i386/ źródeł jądra Linux-a. Jak właściwie wywoływać GCC z kodem inline assemblera. Ponieważ funkcje assemblera w źródłach jądra (i bardzo prawdopodobnie twoje własne nagłówki, jeśli spróbujesz stworzyć twoje oprogramowanie w assemblerze tak czyste jak to jest w jądrze linuxa) są osadzone w funkcjach extern inline, GCC musi zostać wywołąny z -O flag (or -O2, -O3, itd), by te funkcje były dostępne. Jeśli nie, twój kod może się skompiluje, ale nie zostanie właściwie zlinkowany, gdyż będzie szukał funkcji extern które nie są inline w bibliotekach z którymi twój program będzie linkowany !!!. Innym sposobem jest zlinkowanie z bibliotekimi zawierającymi wycofane wersje tych funkcji. Assemblacja inline może zostać wyłączona opcją -fno-asm, która każe zaprzestać kompilatorowi działania gdy zostanie użyte rozszerzenie składni o inline asm, w przeciwnym wypadku wygeneruje wywołanie funkcji zewnętrznej o nazwie asm(), która nie zostanie właściwie rozwiązana przez linker. Opcja -fasm przywraca działanie słowa kluczowego asm. Bardziej ogólnie, dobrymi opcjami dla GCC na platformie x86 są gcc -O2 -fomit-frame-pointer -W -Wallpp -O2 jest dobrym poziomem optymalizacji w większości przypadków. Optymalizacja ponadto zajmuje więcej czasu, otrzymując kod który jest mocno dłuższy, ale tylko trochę szybszy; taka optymalizacja może być użyteczna tylko dla ciasnych pętli (jeśli takie są), którą możesz jakkolwiek zrealizować w assemblerze. W przypadkach gdy koniecznie potrzebujesz silnej optymalizacji ze strony kompilatora dla kilku plików, rozważ użycie -O6. -fomit-frame-pointer pozwala generować kod omijający głupie zarządzanie ramką wskaźników, co daje mniejszy i szybszy kod, i zwalnia rejestry do dalszych optymalizacji. Wyklucza to łatwe użycie narzędzi odpluskwiających (gdb), ale kiedy chcesz ich użyć, nie martw się o rozmiar i prędkość kodu. -W -Wall włącza generowanie wszytkich ostrzeżeń i pomaga wychwycić głupie błędy. Możesz dodać specyficzne dla danego procecora -m486 lub inne flagi tak, że GCC wyprodukuje kod bardziej zaadaptowany dla danego komputera. Zauważ, że EGCS (i chyba GCC 2.8) mają -mpentium i tego typu flagi, podczas gdy GCC 2.7.x i starsze wersje nie. Niezły wybór flag specyfikujących procesor powinien być w jądrze Linux-a. Sprawdź dokumentację texinfo o zainstalowanej u ciebie wersji GCC. -m386 pomoże zoptymalizować wielkość, a także prędkość na komputerach gdzie pamięć jest w pełni wykorzystana, odkąd wielkie programy są przyczyną wymiany pamięci, jakakolwiek "optymalizacja" jest sensowna dla większego kodu. Przy takich ustawieniach, może być pomocne przestanie korzystania z C, i w zamian skorzystanie z języka ułatwiającego kod faktoryzujący (przyp.tłum.) taki jak funkcjonalny język i/lub FORTH; i używać implementacji bazującej na wykorzystaniu bajtów i słów. Zapamiętaj, że możesz używać rożnych flag dla różnych plików, więc używaj maksymalnej optymalizacji tam, gdzie program wykonuje się najdłużej, podczas gdy pozostałe pliki optymalizuj pod względem rozmiaru. Do optymalizacji może być pomocna opcja -mregparm=2 i/lub korespondujące atrybuty funkcji, ale mogą stwarzać wiele problemów podczas linkowania obcego kodu, włączająć w to libc. Są sposoby by właściwie zadeklarować użycie obcych funkcji, tak, że zostaną wygenerowane właściwe wywołania, lecz możesz być zmuszony rekompilować obce biblioteki tak, by używały takich samych konwencji wywołań opartych na rejestrach... Zapamiętaj, że możesz ustawić te flagi jako domyślne edytując plik /usr/lib/gcc-lib/i486-linux/2.7.2.3/specs lub gdziekolwiek on jest w twoim systemie (lepiej nie dodawaj tam -Wall). Dokładną lokalizację plików specyfikatorów GCC w twoim systemie możesz uzyskać wołająć gcc -v. 3.2 GAS GAS jest GNU Assemblerem, na którym opiera się GCC. Gdzie go znaleźć Znajdziesz go w tym samym miejscu gdzie GCC, w paczce o nazwie binutils. Jaka jest składnia AT&T W związku z tym, że GAS został pomyślany by wspierać 32-bitowe kompilatory unixowe używa on standardowej składni ``AT&T'', która składnią mocno przypomina standardowe assemblery m68k, i jest standardem w świecie UNIX-a. Składnia nie jest ani gorsza, ani lepsza niż składnia ``Intel-owska''. Jest po prostu inna. Kiedy będziesz zamierzał używać jej, zauważysz bardziej regularna składnię niż w Intel-u, chociaż trochę nudniejszą. Oto najważniejsze ostrzeżenia odnośnie składni GAS: Nazwy rejestrów są poprzedzone %, więc wygląd rejestrów %eax, %dl itd zamiast tylko eax, dl, itd. Dzięki temu możliwe jest włączanie zewnętrznych symboli w C bezpośrednio w kodzie assemblera, bez zamieszania i konieczności stosowania okropnych podkreśleń jako przedrostków. Kolejność operandów jest następująca: pierwsze źródło, ostatnie przeznaczenie, w przeciwieństwie do konwencji intel-a, gdzie pierwsze jest przeznaczenie, a ostatnie źródło. Odtąd, to co w składni intel-a jest mov ax,dx (wstaw rejestr dx w rejestr ax w składni att będzie wyglądało następująco: mov %dx, %ax. Długość operandu jest wyspecyfikowana przez przyrostek w nazwie instrukcji. Przyrostkiem jest b dla (8-bitów) bajtu, w dla (16-bitów) słowa, i l dla (32-bitów) podwójnego słowa. Na przykład, właściwą składnią powyższej instrukcji będzie movw %dx,%ax. Jakkolwiek, gas nie wymaga ścisłej składni att, więc przyrostek jest opcjonalny, kiedy długość operandu może być wywnioskowana z rejestrów, w przeciwnym przypadku, domyślnie zostanie wstawiony 32-bitowy operand (z ostrzeżeniem). Wymuszające operandy zaznaczone są przyrostkami $, tak jak w addl $5,%eax (dodaj wymuszające long dla wartość 5 do rejestru %eax). Brak przedrostka w operandzie wskazuje, że jest to adres w pamięci; stąd movl $foo,%eax wstawia zawartość adresu zmiennej foo w rejestr %eax, ale movl foo,%eax wstawia zawartość zmiennej foo w rejestr %eax. Indeksacja lub wskazanie pośrednie jest realizowane przez umieszczenie rejestru indeksowego lub wskazania pośredniego (komórki wskazania pośredniego) w nawiasach, np testb $0x80,17(%ebp) (sprawdza najstarszy bit bajtu o offsecie 17 z komórki wskazanej przez %ebp). Istnieje program pomagający w konwersji programów ze składni TASM do składni AT&T. Zobacz ftp://x2ftp.oulu.fi/pub/msdos/programming/convert/ta2asv08.zipGAS ma obszerną dokumentację w formacie TeXinfo, którą można znaleźć co najmniej w dystrybucji źródłowej. Przegląd wyciągniętych stron .info z Emacs-a lub innych programów. Zdarzały się pliki o nazwach gas.doc lub as.doc gdzieś w pakietach źródłowych GAS, ale zostały włączone w dokumentacje TeXinfo. Oczywiście, w razie wątpliwości, alternatywną dokumentacją są same źródła! Sekcją, która szczególnie cię zainteresuje to Machine Dependencies::i386-Dependent:: Znowu, źródła Linux-a (jądra systemu), są dobrymi przykładami; zobacz w linux/arch/i386, następujące pliki: kernel/*.S, boot/compressed/*.S, mathemu/*.S Jeśli piszesz jakiś język, pakiet obsługi wątków, itd. możesz obejrzeć jak inne języki (OCaml, gforth, itd.), lub pakiety obsługi wątków (QuickThreads, MIT pthreads, LinuxThreads, itd), lub cokolwiek, zrób to. Na końcu, po prostu skompiluj program w C do assemblera dzięki czemu zobaczysz interesującą cię składnię. Zobacz sekcję Czy potrzebuję Assemblacji?. Ograniczony tryb 16-bitowy GAS jest 32-bitowym assemblerem, zadaniem którego jest wspomóc 32-bitowy kompilator. Aktualnie ma on jedno ograniczenie 16-bitowego trybu, który zawiera niedokończone użycie 32-bitowych przedrostków do instrukcji, tak więc piszesz 32-bitowy kod, który chodzi w 16-bitowym trybie na 32 bitowym procesorze. W obu trybach, wspiera on 16-bitowe używanie rejestrów, ale nie wspiera 16-bitowego adresowania. Użycie dyrektywy .code16 and .code32 przełącza pomiędzy trybami. Zapamiętaj, że dyrektywa inline assembly asm(".code16\n") pozwoli GCC wygenerować 32-bitowy kod, który uruchomi się w trybie rzeczywistym! Stwierdziłem już, że większa część kodu potrzebnego do pełnego wspomagania 16-bitowego trybu programowania została dodana do GAS przez Bryan'a Ford'a (proszę o potwierdzenie?), ale ostatecznie, nie pojawiła się w żadnej dystrybucji którą sprawdziłem, aż do binutils-2.8.1.x ... więcej informacji na ten temat będzie mile widziane. Cienkim rozwiązaniem jest definiowanie makr (patrz poniżej), które produkuja kod binarny (z .byte) który potrzebujesz tylko dla 16-bitowych instrukcji (prawie żadnych jeśli użyjesz code16 jak powyżej, i możesz spokojnie założyć, że kod będzie działał na zgodnych 32-bitowych procesorach x86). By znaleźć właściwe kodowanie, możesz zainspirować się źródłami 16-bitowych assemblerami. 3.3 GASP GASP jest Preprocesorem GAS. Dodaje makra i trochę milszą składnię do GAS. Gdzie znaleźć GASP GASP jest zawarty razem z GAS w archiwum GNU binutils. Jak to działa Działa jako filtr, w stylu cpp i jemu podobnym. Nie pamiętam szczegółów, ale przychodzi on z własną dokumentacją w texinfo, więc przejrzyj ją (w .info), wydrukuj, prześledź (?). GAS z GASP-em według mnie jest typowym makro-assemblerem. 3.4 NASM Projekt Netwide Assembler wypuszcza jeszcze jeden assembler, napisany w C, który powinien być dość modelowy do ewentualnego wsparcia znanych składni i formatów obiektów. Gdzie znaleźć NASM http://www.cryogen.com/NasmWersja binarna jest na kopii sunsite w devel/lang/asm/ Powinna być także dostępna jako .rpm lub .deb w dystrybucjach RedHat/Debian w dystrybucyjnym contrib. Co to robi W momencie pisania tego HOWTO, wersja NASM to 0.97. Składnia jest w stylu Intel-a. Część makroprocesora jest zintegrowana. Wspierane formaty plików obiektowych to bin, aout, coff, elf, as86, (DOS) obj, win32, (ich własny format) rdf. NASM może być używany jako wspomaganie dla wolnego kompilatora LCC (pliki wspierające są zawarte). NASM rozwija się zbyt szybko by to HOWTO było aktualne. Jeżeli nie używasz BCC jako 16-bitowego kompilatora (który wykracza poza to 32-bitowe HOWTO), powinieneś używać NASM zamiast powiedzmy AS86 lub MASM, ponieważ jest mocno wspierany online i chodzi na wszystkich platformach. Uwaga: NASM przychodzi także z disassemblerem, NDISASM. Jego ręcznie napisany parser powoduje, że pracuje szybciej niż GAS, chociaż oczywiście nie wspiera trzech bilionów różnych architektur. Do x86, on powienien być assemblerem wyboru... 3.5 AS86 AS86 jest 80x86 16- i 32-bitowym assemblerem i jest częścią kompilatora języka C (BCC) Bruce'a Evans'a. Ma on głównie składnię Intel-owską, chociaż różni się nieznacznie np w trybach adresowania. Gdzie dostać AS86 Całkowicie przestarzała wersja AS86 jest dystrybuowana przez HJLu tylko do kompilacji jądra Linux-a, w pakiecie o nazwie bin86 (aktualna wersja 0.4), dostępnej w dowolnym magazynie oprogramowania GCC dla Linux-a. Ale nie radzę nikomu używania go do czegokolwiek innego niż przekompilowania Linux-a. Ta wersja wspiera tylko plik obiektowy hacked minix, który nie jest wspierany przez GNU binutils ani nic innego, i ma parę błędów w trybie 32-bitowym, więc powienieneś lepiej trzymać go tylko do kompilacji Linux-a. Ostatnie wersje Bruce'a Evans'a (bde@zeta.org.au) są publikowane wraz z dystrybucją FreeBSD. No, były: Nie mogę znaleźć źródeł z dystrybucji 2.1 na :( Odtąd, wkładam źródła w moim miejscu: http:///www.tunes.org/~fare/files/bcc-95.3.12.src.tgzProjekt Linux/8086 (aka ELKS) jest w pewnym stopniu pozostałością bcc (chociaż nie sądze by zawierał 32-bitowe łaty). Obejrzyj http://www.linux.org.uk/Linux8086.html ftp://linux.mit.edu/. Między innymi, ostatnie wersje, w przeciwieństwie do HJLu's, wspierają Linux-owy format GNU a.out, więc możesz linkować twój kod z programami Linux-owymi, i/lub używać zwykłych narzędzi z pakietu GNU binutil do manipulacji danymi. Ta wersja może ko-egzystować bez szkody z poprzednią wersją (zobacz poniższe pytanie). BCC z 12 marca 1995 roku i wcześniejsze jego wersje mają brak składnika jakim jest odkładanie/pobieranie ze stosu rejestrów segmentowych jako 16-bitowych, co jest uciążliwe gdy programujesz w trybie 32-bitowym. Łata jest opublikowana w projekcie Tunes http://www.tunes.org/ podstrona files/tgz/tunes.0.0.0.25.src.tgz w rozpakowanym katalogu LLL/i386/ Łata powinna być także dostępna bezpośrednio z http://www.tunes.org/~fare/files/as86.bcc.patch.gz Bruce Evans zaakceptował tę łatę, więc jeśli któregoś dnia pojawi się nowa wersja bcc, powinna zawierać tę łatę... Jak wywołać assembler? Oto wpis GNU Makefile do używania bcc do transformacji .s asm w oba GNU a.out .o obiekt i .l listing: %.o %.l: %.s bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $< Usuń %.l, -A-l, and -A$*.l, jeśli nie chcesz listingu. Jeśli chcesz czegoś więcej niż GNU a.out, możesz przejrzeć dokumentację bcc o wspieranych formatach, i/lub użyć objcopy z pakietu GNU binutils. Gdzie znaleźć dokumentacje Dokumentacje które są, zawierają się w pakiecie bcc. Podręczniki są także dostępne gdzieś pod adresem FreeBSD. Kiedy masz wątpliwości, źródła same w sobie są często dobrą dokumentacją: to nie jest zbyt dobrze komentowane, ale styl programowania jest zrozumiały. Możesz spróbować obejrzeć jak as86 jest używany w Tunes 0.0.0.25... Co jeśli nie mogę już skompilować Linux-a z nową wersją ? Linus jest zasypywany listami i moja łata kompilująca Linux-a z Linuxowym a.out as86 chyba do niego nie dotarła (!) (od tłum. trudno to przetłumaczyć - proszę o poprawki). Teraz, nie powinno to mieć znaczenia: trzymaj tylko as86 z pakietu bin86 w /usr/bin i daj zainstalować bcc dobry as86 w /usr/local/libexec/i386/bcc/as gdzie powinien być. Nie będziesz nigdy wołał wprost tego ``dobrego'' as86, ponieważ bcc robi wszystko właściwie, włączając konwersję to Linux-owego a.out, gdy jest wywołany z właściwymi opcjami; więc assembluj pliki wyłącznie z bcc jako głownym assemblerem, nie bezpośrednio z as86. 3.6 INNE ASSEMBLERY To są inne, nieregularne, opcje, w przypadku, gdy powyższe cię niesatysfakcjonowały (dlaczego?), których nie zalecam w przypadku użytkowania (?), ale mogę udowodnić użyteczność jeśli assembler musi być zintegrowany w oprogramowaniu które rozwijasz (np. OS lub aplikacje rozwojowe). Win32Forth assembler Win32Forth jest wolnym 32-bitowym systemem ANS FORTH który działa pod Win32s, Win95, Win/NT. Zawiera wolny 32-bitowy assembler (zawiera przed/przyrostkową składnię) zintegrowany w języku FORTH. Przetwarzanie makr jest przez pełną moc języka FORTH; jakkolwiek, jedynym wspieranym wejścia i wyjścia jest Win32For (żadnego zrzutu do plików .obj -- możesz oczywiście dodać to samemu). Znajdziesz to na ftp://ftp.forth.org/pub/Forth/win32for/ Terse Terse jest narzędziem programowania dostarczającym NAJBARDZIEJ zwartą składnie assemblera dla rodziny x86! Zobacz http://www.terse.com. Mówiono, że jest gdzieś jakiś wolny klon który został porzucony po pustych pretensjach, że składnia powinna być własnością autora; i zapraszam cię do przejęcia tego, jeśli taka składnia cię interesuje. Nie-wolne i/lub Nie-32bitowe x86 assemblery. Możesz znaleźć więcej o nich, wraz z podstawami programowania w assemblerze x86 w FAQ Raymond'a Moon'a dla comp.lang.asm.x86 http://www2.dgsys.com/~raymoon/faq/asmfaq.zipZapamiętaj, że wszystkie bazujace na DOS-ie assemblery powinny pracować w Linuxowym emulatorze DOS-u tak dobrze jak inne podobne emulatory, więc jeśli już masz jakiś możesz go nadal używać w prawdziwym OS. Ostatnie assemblery bazujące na DOS-ie także wspierają COFF i/lub inne formaty plików obiektowych, które są wspierane przez bibliotekę GNU BFD, więc możesz używać ich razem z wolnymi 32-bitowymi wolnymi narzędziami, być może używająć GNU objcopy (część binutils) jako filtr konwertujący. Następna strona Poprzednia strona Spis treści

Wyszukiwarka

Podobne podstrony:
Assembly HOWTO pl 5 (2)
Assembly HOWTO pl 4 (2)
assembly howto pl
Assembly HOWTO pl 7 (2)
Assembly HOWTO pl (2)
Assembly HOWTO pl 6 (2)
Assembly HOWTO pl 2 (2)
Assembly HOWTO pl 1 (2)
bootdisk howto pl 8
PPP HOWTO pl 6 (2)
NIS HOWTO pl 1 (2)
cdrom howto pl 1
jtz howto pl 5
Keystroke HOWTO pl (2)
PostgreSQL HOWTO pl 14
printing howto pl 5
debian apt howto pl
Kernel HOWTO pl 12 (2)
XFree86 HOWTO pl (3)

więcej podobnych podstron