Asembler X86/Pierwszy program/GNU AS
Z Wikibooks, biblioteki wolnych podręczników.
[edytuj] Hello world! (POSIX)
Oto przykład programu, napisanego w asemblerze GNU, wyświetlającego napis "Hello World!" w systemie zgodnym z normą POSIX, uruchomionym na komputerze typu i386:
.text .global _start _start: movl $4, %eax movl $1, %ebx movl $napis, %ecx movl $len, %edx int $0x80 movl $1, %eax movl $0, %ebx int $0x80 .data napis: .string "hello world!\n" len = . - napis
Aby skompilować powyższy program musisz wydać następujące polecenia. Najpierw trzeba kod zasemblować aby uzyskać plik obiektowy *.o:
as hello.s -o hello.o
Tak otrzymany kod wynikowy, musisz poddać działaniu linkera ld:
ld hello.o -o hello
Teraz dopiero program jest wykonywalny. Możesz go uruchomić w konsoli wydając polecenie w katalogu w którym jest program:
./hello
Omówię teraz po kolei kod tego programu:
.text .global _start
Ten fragment informuje asembler, że informacje tutaj zawarte są kodem programu, a etykieta _start ma być etykietą globalną (umożliwi to m.in. wykorzystanie tej etykiety jako głównej funkcji programu).
_start:
"Zawartość" etykiety _start.
movl $4, %eax movl $1, %ebx movl $napis, %ecx movl $len, %edx int $0x80
Instrukcja mov (l na końcu to informacja, że zapisujemy dane do 32-bitowego rejestru) przenosi dane do odpowiednich rejestrów - w EAX znajdzie się numer funkcji systemowej (4 - write), EBX - plik docelowy (1 - standardowe wyjście), w ECX - adres, pod którym znajdują się dane do wyświetlenia oraz EDX - długość napisu. Instrukcja int powoduje wywołanie przerwania i realizację przez system operacyjny odpowiedniej czynności - w tym przypadku wypisanie na ekran "Hello world!".
movl $1, %eax movl $0, %ebx int $0x80
Tym razem wywołamy funkcję exit, której argumentem będzie 0. W ten sposób "poprosimy" system operacyjny o zakończenie pracy programu.
.data
Oznacza, że dalsza część programu będą stanowiły dane, potrzebne do wykonania instrukcji.
napis:
Nie używamy .globl - etykieta napis ma być widoczna tylko dla kodu programu i nie jest istotna w procesie tworzenia pliku wykonywalnego.
.string "hello world!\n"
Tworzymy napis, który będzie widoczny pod adresem etykiety "napis".
len = . - napis
Jest to zmienna, która zawiera długość napisu. Kropka oznacza "aktualny adres" w pamięci (w naszym przypadku koniec napisu), a "napis" - adres etykiety, pod którą zawarto początek napisu. Różnica koniec - początek daje długość napisu, która jest niezbędna, aby program wypisał na ekranie dokładnie tyle znaków, ile liczy sobie napis.
[edytuj] Hello World! (wersja DOS)
Analogiczny program, który kompiluje się pod systemem DOS(będąc emulowanym pod Windowsem) mógłby wyglądać np. tak:
.data napis: .string "Hello World!\n$" .text .globl _start _start: movw $napis, %dx movb $9, %ah int $0x21 movw $0x4C00, %ax int $0x21
Przyglądając się składni GNU możesz zauważyć, jak bardzo różni się ona od składni NASM lub MASM.