   #Start Prev Next Contents

   Jak pisac programy w jezyku asembler pod Linuksem?

Czesc 12 - Czego od nas pragna, czyli linia polecen programu. Zmienne
srodowiska

   Teraz zajmiemy sie dosc istotna sprawa z punktu widzenia programisty i
   uzytkownika oprogramowania: linia polecen. Nie wszyscy lubia podawac
   dane programowi w czasie jego pracy i odpowiadac na pytania o dane.
   Czesto (o ile jest to mozliwe) mozna tego oszczedzic i zamiast
   bezustannie zadawac uzytkownikowi pytania, przeczytac, co wpisano nam
   w linie polecen. Umozliwia to pisanie programow, ktore raz uruchomione
   z prawidlowa linia polecen nie pytaja juz sie o nic a tylko wykonuja
   swoja prace bez przeszkadzania uzytkownikom.

   Przejdzmy wiec do szczegolow. Jesli ktos z Was zna jezyk C, to na
   pewno wie, jak zadeklarowac funkcje glowna programu tak, aby mogla
   odczytac parametry i zmienne srodowiska. Deklaracja taka wyglada
   zazwyczaj tak:
                int main (int argc, char *argv[], char *env[])

   gdzie:
     * argc - liczba calkowita mowiaca o tym, z jaka iloscia parametrow
       uruchomiono nasz program.
     * char *argv[] - tablica wskaznikow do poszczegolnych parametrow.
       Tutaj, argv[0] - nazwa uruchomionego programu, argv[1] - pierwszy
       parametr programu itd.
     * char *env[] - tablica wskaznikow do zmiennych srodowiskowych.

   Ale gdzie sa te zmienne?
   Na stosie, oczywiscie!
   Po wykonaniu typowego prologu do funkcji (czyli push ebp / mov ebp,
   esp), zmienna "argc" znajduje sie w [ebp+4], wskazniki do parametrow
   linii polecen zaczynaja sie od [ebp+8] i ida w gore stosu, po nich
   jest wskaznik zerowy i dalej w gore sa wskazniki do zmiennych
   srodowiska, tez zakonczone wskaznikiem zerowym.

   Wszystko ladnie wyglada w teorii, ale jak tego uzywac?
   Aby odpowiedziec na to pytanie, napisalem ten oto krotki programik.
   Jedynym celem jego zycia jest wyswietlenie, z iloma argumentami go
   wywolano (co najmniej jeden - nazwa programu), wyswietlenie tych
   argumentow i zmiennych srodowiska.
   A teraz kod:
   (przeskocz program wyswietlajacy linie polecen)
; Program wyswietla wlasna linie polecen i zmienne srodowiskowe.
;
; Autor: Bogdan D.
; kontakt: bogdandr (at) op (dot) pl
;
; nasm -O999 -f elf liniap.asm
; ld -s -o liniap liniap.o bibl/lib/libasmio.a
;
; fasm liniap.asm liniap.o
; ld -s -o liniap liniap.o bibl/lib/libasmio.a

        ; przyda sie nam moja biblioteczka
%include "bibl/incl/linuxbsd/nasm/std_bibl.inc"
section .text
global _start

; FASM:
; format ELF
; include "bibl/incl/linuxbsd/fasm/std_bibl.inc"
; section ".text" executable
; public _start


_start:
        push    ebp             ; typowy prolog, o ktorym wspomnialem
        mov     ebp, esp

%idefine        argc    ebp+4           ; liczba parametrow
%idefine        argv    ebp+8           ; parametry

; FASM:
;       argc    equ     ebp+4           ; liczba parametrow
;       argv    equ     ebp+8           ; parametry


        mov     eax, [argc]             ; EAX = liczba parametrow
        pisz32e                         ; wypisz EAX
        nwln                            ; przejdz do nowej linii

        xor     edi, edi                ; zerujemy licznik
                                        ; wyswietlonych parametrow

wypisz_argv:
        cmp     edi, eax                ; czy liczba wyswietlonych =
                                        ; = liczba parametrow?
        je      koniec_wypisz_argv      ; jesli tak, to koniec
                                        ; wyswietlania parametrow

        mov     esi, [argv+edi*4]       ; pobierz parametr numer EDI.
                                        ; kazdy wskaznik jest czterobajtowy,
                                        ; dlatego mnozymy EDI przez 4.

        pisz_esi                        ; wypisz napis pod adresem ESI
                                        ; czyli nasz parametr
        nwln                            ; przejdz do nowej linii

        add     edi, 1                  ; wybieramy kolejny parametr
        jmp     short   wypisz_argv     ; i idziemy pisac od nowa

koniec_wypisz_argv:
                        ; parametry sie skonczyly. Teraz bedzie jeden
                        ; wskaznik zerowy i zmienne srodowiska

        inc     edi                     ; przeskocz wskaznik zerowy

wypisz_env:
        mov     esi, [argv+edi*4]       ; pobierz zmienna srodowiskowa

        test    esi, esi                ; sprawdz, czy nie wskaznik zerowy
        jz      koniec_wypisz_env       ; jesli zero, to skonczylismy

        pisz_esi                        ; wypisz zmienna srodowiskowa
        nwln                            ; przejdz do nowej linii

        add     edi, 1                  ; przechodzimy na kolejna zmienna
        jmp     short   wypisz_env      ; i wypisujemy dalej


koniec_wypisz_env:
        wyjscie                         ; koniec...

   Jak widac, nie bylo to az takie trudne jak sie moglo zdawac na
   poczatku. Wlasnie poznaliscie kolejna rzecz, ktora jest latwa w
   uzyciu, a mozliwosci ktorej sa duze. Teraz bedziecie mogli smialo
   zaczac pisac programy, ktorych jedynym kanalem komunikacyjnym z
   uzytkownikiem bedzie linia polecen, co znacznie uprosci ich obsluge.

   Tylko pamietajcie o dodaniu kodu wyswietlajacego sposob uzycia
   programu, gdy nie podano mu zadnych parametrow.

   Poprzednia czesc kursu (klawisz dostepu 3)
   Kolejna czesc kursu (klawisz dostepu 4)
   Spis tresci off-line (klawisz dostepu 1)
   Spis tresci on-line (klawisz dostepu 2)
   Ulatwienia dla niepelnosprawnych (klawisz dostepu 0)
     _________________________________________________________________

Cwiczenia

    1. Napisz program, ktory utworzy plik podany jako parametr. Jesli
       podano drugi parametr (oddzielony od pierwszego spacja), zapisz
       jego wartosc do tego pliku. Jesli nie podano zadnych parametrow,
       niech program wypisze stosowna wiadomosc.
    2. Napisz program, ktory oblicza NWD (patrz czesc 8) dwoch liczb
       podanych na linii polecen. Jesli nie podano wystarczajacej liczby
       parametrow, niech program wyswietli stosowna wiadomosc.
