Asembler x86/Łączenie z językami wysokiego poziomu/Funkcje zewnętrzne
Wygląd
Poniższy przykład pokazuje, jak bezpośrednio w kodzie asemblera wykorzystać funkcję printf() znaną z języka C.
global main
extern printf
section .data
beer db "%d bottles of beer on the wall, %d bottles of beer."
db 0x0a
db "Take one down and pass it around, %d bottles of beer."
db 0x0a
db 0
main:
mov ecx, 5 ; deklarowana liczba przebiegów pętli
_loop:
dec ecx ; ECX = ECX-1
push ecx ; umieszcza aktualny indeks pętli na stosie
push ecx ; argumenty funkcji printf() umieszczamy na stosie
inc ecx ; w odwrotnej kolejności, tj. od prawej do lewej strony
push ecx
push ecx
push beer
call printf ; wywołanie funkcji printf(beer,ecx,ecx,ecx-1)
add esp,16 ; zdejmujemy jej argumenty ze stosu
pop ecx ; pobieramy ze stosu aktualny indeks pętli
or ecx, ecx ; ustala wartość flagi ZF=0, jeśli ECX=0
jne _loop ; warunkowy skok do początku pętli, gdy flaga ZF=0
xor eax,eax ; EAX = 0
ret ; return EAX
W celu kompilacji i linkowania programu należy wykonać polecenia:
nasm -f elf -o beer.o beer.asm
gcc -s -o beer beer.o
Po czym możemy uruchomić program:
user@myhost:~$ ./beer
5 bottles of beer on the wall, 5 bottles of beer.
Take one down and pass it around, 4 bottles of beer.
4 bottles of beer on the wall, 4 bottles of beer.
Take one down and pass it around, 3 bottles of beer.
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottles of beer.
1 bottles of beer on the wall, 1 bottles of beer.
Take one down and pass it around, 0 bottles of beer.
user@myhost:~$