Asembler X86/Pierwszy program/FASM

Z Wikibooks, biblioteki wolnych podręczników.

[edytuj] Hello World!

Zacznijmy od dawki kodu, aby w ogóle mieć pojęcie, jak wygląda kod w języku Asembler. 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!). Uwaga: jak już wcześniej było wspomniane, konkretny kod zapisany w Asemblerze wykonuje się na konkretnej maszynie. Poniższy program uruchomi się tylko pod systemem Windows.

format MZ
 
entry kod:start
 
segment dane
        tekst db "Hello World!",0Ah,0Dh,"$"
 
segment kod
    start:
	mov ax, dane
        mov ds, ax
 
        mov dx, tekst
        mov ah, 9
        int 0x21
        mov ax, 0x4C00
        int 0x21

A teraz postaram się zrozumiale wyjaśnić poszczególne fragmenty kodu.

format MZ

Informuje asemblera FASM, że ma utworzyć dosowy plik wykonywalny MZ.

entry kod:start

Powiadamia gdzie znajduje się adres wejściowy dla pliku wykonywalnego (z którego adresu ma rozpocząć się wykonywanie kodu); kod jest to nazwa segmentu zaś po dwukropku znajduje się nazwa etykiety która jest przypisana do żądanego adresu (zarówno wykorzystany tu segment jak i etykieta są zdefiniowanie poniżej).

segment dane

Tworzy segment o nazwie dane i przechodzi do jego definiowania.

tekst db "Hello World!",0Ah,0Dh,"$"

Tworzy wewnątrz obecnie definiowanego segmentu (tj. segmentu dane) ciąg "Hello World" zakończony znakiem nowej linii oraz znakiem dolara (znak dolara w funkcjach dosowych oznacza koniec ciągu znaków dlatego musi się tu znaleźć).

start:

Definiuje etykietę o nazwie start.

mov ax, dane
mov ds, ax

Kopiuje adres segmentu dane do rejestru AX a następnie z rejestru AX do rejestru DS (do rejestrów segmentowych nie można przypisywać bezpośrednio adresów dlatego musiał tu pośredniczyć jakiś inny rejestr).


mov dx, tekst
mov ah, 9
int 0x21

Ten fragment kodu zacznę tłumaczyć od końca. Instrukcja int wywołuje podprogram obsługi przerwania o podanym numerze (poprzedzenie go przedrostkiem 0x oznacza liczbę w zapisie szesnastkowym). Podprogram ów wywołuje odpowiednią funkcję o numerze podanym w rejestrze ah (wcześniej nadaliśmy temu rejestrowi wartość 9, więc instrukcja int 0x21 wywołała funkcję numer 9 przerwania numer 21 w zapisie szesnastkowym). Wywołana w tym przypadku funkcja wyświetla w konsoli ciąg znaków, którego adres znajduje w rejestrze dx (przydzieliliśmy temu rejestrowi adres naszej zmiennej tekst). W efekcie na ekranie pojawi się więc napis Hello World!.
Uwaga: należy zaznaczyć, że przerwanie 21h oraz opisana funkcja obsługiwane są przez MS-DOS, przez co kod nie jest przenośny na inne platformy niz Windows.

mov ax, 0x4C00
int 0x21

Wywołuje funkcję przerwania 21 o numerze 0x4C00. Odpowiada ona za zakończenie działania programu i oddanie sterowania do systemu. Jeszcze tylko na koniec taka mała ciekawostka na temat wartości zapisywanej do rejestru AX. Zapisujemy tutaj 0x4C00. Dolny bajt - 0x00 oznacza kod błędu jaki zwracamy systemowi operacyjnemu. Jeśli dalibyśmy np 0x4C13 to nasz program zwrócił by kod błędu równy własnie liczbie 0x13.