Przejdź do zawartości

Asembler x86/Pierwszy program/FASM

Z Wikibooks, biblioteki wolnych podręczników.

Pierwszy program

GNU As
FASM
MASM
NASM

Hello World!

[edytuj]

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 Linux.

format ELF

entry .text:_start

segment .data
        tekst db "Hello World!\n"

segment .text
    _start:
        xor ebx, ebx
        mov ecx, tekst
        mov eax, 4
        inc ebx
        mov edx, 13
        int 80H
        mov eax, 1
        xor ebx, ebx
        int 80H

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

format ELF

Informuje asembler, że ma utworzyć linuxowy plik wykonywalny ELF.

entry .text:_start

Powiadamia gdzie znajduje się adres wejściowy dla pliku wykonywalnego (z którego adresu ma rozpocząć się wykonywanie kodu); .text 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 .data

Tworzy segment o nazwie .data i przechodzi do jego definiowania.

tekst db "Hello World!\n$"

Tworzy wewnątrz obecnie definiowanego segmentu (tj. segmentu .data) ciąg "Hello World" zakończony znakiem nowej linii.

_start

Definiuje etykietę o nazwie _start.

xor ebx, ebx

Wykonuje na rejestrze EBX operację XOR. Prawy operand to rejestr EBX. Wynika że, następujące działanie (niech daszek ^ oznacza operację XOR): EBX ^ EBX = 0 Tak więc xor ebx, ebx zeruje rejestr EBX.

mov ecx, tekst
mov eax, 4
mov ebx, 1
mov edx, 13
int 80h

Ten fragment kodu zacznę tłumaczyć od końca. Instrukcja int wywołuje podprogram obsługi przerwania o podanym numerze (zakończenie go przyrostkiem H oznacza liczbę w zapisie szesnastkowym). Podprogram ów wywołuje odpowiednią funkcję o numerze podanym w rejestrze eax (wcześniej nadaliśmy temu rejestrowi wartość 4, więc instrukcja int 80H wywołała funkcję numer 4 przerwania numer 80 w zapisie szesnastkowym). Wywołana w tym przypadku funkcja wyświetla w konsoli ciąg znaków, którego adres znajduje w rejestrze ecx (przydzieliliśmy temu rejestrowi adres naszej zmiennej tekst) do napotkania znaku o numerze w rejestrze edx. W efekcie na ekranie pojawi się więc napis Hello World!.
Uwaga: należy zaznaczyć, że przerwanie 80h oraz opisana funkcja obsługiwane są przez Unix, przez co kod nie jest przenośny na inne platformy niż Linux.

mov eax, 1
dec ebx
int 80h

Wywołuje funkcję przerwania 80 o numerze 1. Odpowiada ona za zakończenie działania programu i oddanie sterowania do systemu za pomocą kodu wyjścia w rejestrze EBX (instrukcja dec zmniejsza wartość o 1, przez co ebx jest teraz równy 0).