Czasem zdarza się, że z poziomu naszego własnego programu musimy uruchomić jakiś inny program lub polecenie systemowe. Służy do tego funkcja systemowa sys_execve (numer 11). Jej argumenty to kolejno:
Spróbujmy więc napisać jakiś prosty przykład - wyświetlenie napisu za pomocą programu echo.
; Uruchamianie innych programów w asemblerze pod Linuksem ; ; Autor: Bogdan D., bogdandr (at) op.pl ; ; kompilacja: ; ; nasm -f elf -o exec_linux.o exec_linux.asm ; ld -o exec_linux exec_linux.o section .text global _start _start: mov eax, 11 ; numer funkcji sys_execve mov ebx, komenda ; plik do uruchomienia mov ecx, argumenty ; adres tablicy argumentów mov edx, srodowisko ; adres tablicy środowiska int 80h mov eax, 4 mov ebx, 1 mov ecx, info mov edx, info_dl int 80h ; wyświetlenie napisu mov eax, 1 xor ebx, ebx int 80h ; wyjście z programu section .data komenda db "/bin/echo", 0 ; program do uruchomienia info db "Wykonalem program.", 10 ; napis do wyświetlenia info_dl equ $ - info argumenty dd komenda ; argv[0] to nazwa programu dd arg1 ; argv[1] dd 0 ; koniec argumentów arg1 db "Czesc!", 0 ; argument pierwszy srodowisko dd home ; jedna zmienna środowiskowa dd 0 ; koniec zmiennych środowiskowych home db "HOME=/home/bogdan", 0 ; przykładowa zmienna ; środowiskowa $HOME
Jedna rzecz od razu powinna rzucić się
w oczy: napis Wykonałem program
nie jest wyświetlany.
Dzieje się tak dlatego, że jeśli funkcja
sys_execve wykonała się bez błędów, to ... nie powróci do naszego programu
(tak, jak jest to napisane na stronie podręcznika: man execve). Duża wada, ale można
to łatwo przeskoczyć, stosując wątki lub funkcje typu sys_fork
lub sys_clone, w celu uruchomienia
osobnego wątku lub procesu, który potem wykona sys_execve.