Asembler x86/Pierwszy program/MASM: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
m poprawa linków do podstron podręcznika Asembler x86 z powodu zmiany nazwy
Nie podano opisu zmian
Linia 5:
Zacznijmy od dawki kodu, żeby mieć pojęcie jak w ogóle wygląda kod asemblera. Będzie to tradycyjny już program ''Hello World'', który można napotkać w niemal każdym podręczniku do nauki programowania w dowolnym języku (za zadanie ma po prostu wyświetlenie napisu ''Hello World!'').
 
<sourcesyntaxhighlight lang="asm">
.model SMALL
.386
Linia 21:
.exit
end
</syntaxhighlight>
</source>
 
Wygląda strasznie? Na pewno. Postaram się zrozumiale wyjaśnić o co w nim chodzi.
<sourcesyntaxhighlight lang="asm">
.model SMALL
</syntaxhighlight>
</source>
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.
<sourcesyntaxhighlight lang="asm">
.386
</syntaxhighlight>
</source>
Ta dyrektywa określa z jakiego zbioru instrukcji będzie korzystać nasz program. W tym przypadku określamy oczywiście, że chodzi nam o zbiór instrukcji procesorów 80386.
<sourcesyntaxhighlight lang="asm">
.data
</syntaxhighlight>
</source>
Określa, że od tego miejsca w dół definiowany jest segment z danymi.
<sourcesyntaxhighlight lang="asm">
tekst db "Hello World!\n"
</syntaxhighlight>
</source>
Wrzuca do segmentu z danymi ciąg znaków "Hello World!" zakończony znakiem nowej linii. ''tekst'' jest to nazwa dla naszego ciągu, zaś słowo ''db'' oznacza, że ma być on ciągiem bajtów.
<sourcesyntaxhighlight lang="asm">
.stack 100h
</syntaxhighlight>
</source>
Dyrektywa tworzy segment stosu o wielkości 100h. Umieszczenie literki ''h'' za liczbą oznacza, że '''jest zapisana szesnastkowo''' (100h = 256 dziesiętnie).
<sourcesyntaxhighlight lang="asm">
.code
</syntaxhighlight>
</source>
Początek definiowania segmentu z kodem.
<sourcesyntaxhighlight lang="asm">
.startup
</syntaxhighlight>
</source>
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).
<sourcesyntaxhighlight lang="asm">
mov ecx, offset tekst
</syntaxhighlight>
</source>
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).
<sourcesyntaxhighlight lang="asm">
mov eax, 4
mov edx, 13
mov ebx, 1
</syntaxhighlight>
</source>
Kopiuje wartość 4 do naszego rejestru eax, 1 do ebx, i 13 do edx.
<sourcesyntaxhighlight lang="asm">
int 80h
</syntaxhighlight>
</source>
Instrukcja int wywołuje podprogram obsługi przerwania (dokładnie co to są przerwania opisane jest w rozdziale [[Asembler x86/Przerwania|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 eax (przerwanie 80h, funkcja przerwania numer 4).
<sourcesyntaxhighlight lang="asm">
.exit
</syntaxhighlight>
</source>
Jest to 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 (tzn. makroinstrukcja ta nie przypisuje żadnych wartości rejestrom innym niż ah określającemu numer funkcji). Funkcja ta kończy działanie programu.
<sourcesyntaxhighlight lang="asm">
end
</syntaxhighlight>
</source>
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.