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

Usunięta treść Dodana treść
Mythov (dyskusja | edycje)
Mythov (dyskusja | edycje)
Linia 26:
== Zaczynamy! ==
=== Hello world! ===
Zacznijmy od dawki kodu, żeby mieć pojęcie jak to w ogóle wygląda:
<pre>
.model small
.386
 
.data
tekst byte "Hello World!",0Ah,0Dh,"$"
.stack 100h
.code
.startup
mov dx, offset tekst
mov ah, 09h
int 21h
.exit
end
</pre>
Program ten po uruchomieniu w konsoli wyświetla na ekranie tekst "Hello World!". Postaram się zrozumiale wyjaśnić o co w nim chodzi.
.model small
Dyrektywa .model pozwala zdefiniować z jakiego modelu pamięci ma korzystać nasz program. Model small oznacza segmentowy model pamięci z jednym segmentem kodu i jednym segmentem danych.
.386
Ta dyrektywa określa z jakiego zbioru instrukcji będzie korzystać nasz program. W tym przypadku chodzi określamy oczywiście, że chodzi nam o zbiór instrukcji procesorów 80386.
.data
Określa, że od tego miejsca w dół definiowany jest segment z danymi.
tekst byte "Hello World!",0Ah,0Dh,"$"
Wrzuca do segmentu z danymi ciąg znaków "Hello World!" zakończony znakiem nowej linii (0A0D) oraz znakiem $ określającym, iż jest to koniec naszego ciągu znaków (dla migrantów z C/C++ - jest to odpowiednik znaku '\0'). ''tekst'' jest to nazwa dla naszego ciągu, zaś słowo ''byte'' oznacza, że ma być on ciągiem bajtów.
.stack 100h
Dyrektywa tworzy segment stosu o wielkości 100h. Umieszczenie literki ''h'' za liczbą oznacza, że '''jest zapisana szesnastkowo''' (100h = 256 dziesiętnie).
.code
Początek definiowania segmentu z kodem.
.startup
Jest to makroinstrukcja, która w procesie kompilacji zastępowana jest w tym miejscu kodem wykonującym standardowe początkowe czynności (nadaje odpowiednie wartości rejestrom segmentowym, które są konieczne do poprawnego działania naszego programu).
mov dx, offset tekst
Jeśli zdeasemblujesz dowolny program, prawdopodobnie ujrzysz instrukcje podobne do tej umieszczone jedna za drugą. Każdej instrukcji asemblera używa się wg. schematu:
instrukcja argumentA, argumentB, argumentC...
Jeśli chodzi o akurat tą instrukcję - mov kopiuje zawartość B do A. A w tym przypadku to rejestr procesora dx, zaś B (''offset tekst'') to adres naszego ciągu znaków, wydobyty dzięki słowu ''offset'' (użycie samej nazwy zmiennej nie odnosiłoby się do jej adresu a o niego nam w tym przypadku chodzi).
mov ah, 09h
Kopiuje wartość 09h do naszego rejestru ah.
int 21h
Instrukcja int wywołuje podprogram obsługi przerwania (dokładnie co to są przerwania opisane jest w rozdziale [[Asembler X86/Instrukcje_specjalne|Instrukcje]]) o numerze podanym jako A (w tym przypadku chodzi o numer 21h). Podprogram obsługujący przerwanie o tym numerze wywołuje określoną funkcję o numerze przekazanym w rejestrze ah (przerwanie 21h, funkcja przerwania numer 09h).
.exit
Makroinstrukcja wywołująca przerwanie 21h, funkcję 4Ch (dla ćwiczenia spróbuj zastąpić ją właściwym kodem przy użyciu instrukcji mov oraz int), która nie przyjmuje żadnych argumentów (makroinstrukcja nie przypisuje żadnych wartości rejestrom innym niż ah określającym numer funkcji). Funkcja ta kończy działanie programu.
end
Określa że w tym miejscu kończy się kod. Asembler po napotkaniu tego słowa kończy proces asemblacji, niezależnie od tego, czy znajduje się jakiś kod jeszcze dalej.
 
=== Goodbye world... ===