Asembler x86/Podstawy: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Mythov (dyskusja | edycje)
Lethern (dyskusja | edycje)
m drobne
Linia 2:
 
== Instrukcje ==
Instrukcje (nie mylić z funkcjami!), których będziemy używać w asemblerze są '''bezpośrednio tłumaczone''' na "język" procesora. Oznacza to, że każda instrukcja, której użyjemy w kodzie, wywołuje konkretną, niepodzielną na mniejsze (przynajmniej w większości przypadków) reakcję procesora. W językach wysokiego poziomu nie operujemy na takim poziomie. Pozornie proste "wyższe" konstrukcje językowe są zamieniane na kilka, kilkanaście instrukcji procesora przez co w efekcie nie mamy bezpośredniej kontroli nad wynikowym kodem. Ograniczenie to nie dotyczy nas, gdy programujemy z użyciem asembleraAsemblera. Lista instrukcji procesora znajduje się w rozdziale [[../Instrukcje|Instrukcje]]. Jak już pewnie spostrzegłeśspostrzegłe(a)ś, jest ich mnóstwo, zapamiętanie wszystkich z nich jest bardzo czasochłonne; najłatwiej przychodzi w praktyce. Każdej instrukcji używa się wg. schematu:
instrukcja parametr1, parametr2, parametr3
Jako parametry (zamiennie, możemy je nazywać ''argumentami'' lub ''operandami'') możemy przekazywać: rejestry, adresy do pamięci i nazwy symboliczne, przy czym ich liczba jest zależna od użytej instrukcji i wacha się w przedziale od 0 do 3 argumentów. Niektóre instrukcje występują w kilku/kilkunastu(nastu) wersjach o identycznej nazwie, z różną ilością parametrów. Instrukcje powinny znajdować się jedynie w obszarach kodu definiujących segmenty. Używanie ich poza nimi może być kłopotliwe.
 
== Etykiety ==
Etykiety (ang. ''label'') istnieją jedynie na poziomie kodu asemblerowego. Po asemblacji nie pozostaje po nich żaden ślad. Służą do nazywania konkretnych adresów w pamięci. Znacznie zwiększają czytelność i elastyczność kodu, gdyż operowanie na liczbach określających adresy w pamięci jest skrajnie niewygodne. Aby przydzielić etykietę do adresu, korzystamy z poniższego prostego schematu:
etykieta:
Etykieta musi znajdować się na początku linii, i być niepoprzedzona niczym innym. Gdy już połączymy to już z naszą dotychczasową wiedzą o korzystaniu z instrukcji, możemy napisać prosty przykład:
<source lang="asm">etykieta: mov eax, ecx</source>
Od tej pory, gdy będziemy chcieli odnieść się do tego adresu (np. gdy zechcemy przeskoczyć w wykonaniu naszego programu bezpośrednio w miejsce z naszą instrukcją ''mov''), możemy napisać po prostu:
<source lang="asm">jmp etykieta</source>
zamiast podawać cyferki adresu w pamięci (instrukcja jmp modyfikuje rejestr [[../Architektura#EIP|EIP]], przez co procesor "przeskakuje" do innego kodu; więcej o tej instrukcji w rozdziale [[../Funkcje|Funkcje]]). Dodatkowo, poprzedni kod, który zdefiniowaliśmy, jest równoznaczny z poniższym:
<source lang="asm">
etykieta:
mov eax, ecx
</source>
Jak zapewne zauważyłeśzauważyłe(a)ś, definicja etykiety podczepia się automatycznie pod najbliższą linijkę (jednak nie zawsze obowiązuje ta zasada!).
 
== Komentarze ==
Komentarz jest to po prostu notatka mająca ułatwić zrozumienie danego fragmentu kodu innym, którzy będą go czytać oraz przede wszystkim temu, kto go napisał. Jeśli programista daruje sobie komentowanie kodu, orientowanie się w nim będzie zajmowało mu więcej czasu, lub też zajmie mu to nieskończoną ilość czasu, gdyż z obłędem w oczach skasuje całą swoją pracę nie mogąc zrozumieć ani jednej linijki. Komentarze istnieją jedynie na poziomie kodu źródłowego, po kompilacji nie pozostaje po nich żaden ślad. Aby uczynić dowolny tekst komentarzem i tym samym wyłączyć go z procesu asemblacji, należy poprzedzić go średnikiem. Średnik zamienia w komentarz wszystko, co znajduje się za nim, aż do końca linii.
<source lang="asm">mov eax, edx ; to jest komentarz</source>
 
'''Asembler MASM''' umożliwia jeszcze jedną metodę komentowania:
comment granica komentarz granica
Przy czym jako ''granica'' wstawiamy dowolny znak np.
Linia 32:
a to już nie
 
'''GNU Assembler''' z kolei ma zupełnie inną składnię komentarzy. Aby objąć dowolny blok komentarzem, należy umieścić go między /* oraz */ (zapewne ten sposób komentowania jest znajomy dla programistów C). W przypadku tego asemblera, dozwolone jest również używanie znaku # , który ma identyczne działanie jak znak ; (średnik) w przypadku innych asemblerów.
 
== Struktura kodu asemblera ==
Kod asemblerowy to instrukcje, pogrupowane w segmenty. To w nich znajduje się cała esencja naszego programu. Poza nimi definiuje się raczej jedynie różne struktury, makroinstrukcje, które same w sobie nie pozostawiają żadnego śladu w zasemblowanym kodzie. Mimo to asemblery są bardzo elastyczne i pozwalają na umieszczanie instrukcji wszędzie, nawet poza obszarami definiującymi segmenty, przy czym stale zachowany jest porządek góra-dół, tzn. to co znajduje się wyżej w kodzie, jest wyżej w pliku wykonywalnym (tzn. bliżej jego początku,); zaś to, co znajduje się niżej w kodzie, jest niżej w pliku wykonywalnym. Oczywiście, ten porządek może zostać w mniejszym lub większym stopniu zakłócony poprzez stosowanie najróżniejszych opcjonalnych makroinstrukcji i dyrektyw, jednak sam czysty kod asemblerowy podchodzi pod definicję.
 
<noinclude>{{Nawigacja|Asembler X86|