   #Start Contents English version

                   Dynamiczna alokacja pamieci pod Linuksem

   Juz w srednio zaawansowanych programach pojawia sie potrzeba
   dynamicznego rezerwowania pamieci, w czasie dzialania programu, nie
   wiedzac z gory, ile pamieci bedzie potrzeba. Na przyklad, uzytkownik
   podaje nam rozmiar tablicy a my musimy taka tablice utworzyc i na niej
   operowac (nie znajac wczesniej nawet maksymalnego jej rozmiaru).
   Rozwiazaniem takich problemow jest wlasnie dynamiczna alokacja
   pamieci. Pod Linuksem pamiec alokuje sie funkcja sys_brk (ustalajaca
   najwyzszy dostepny adres w sekcji danych). Przyjmuje ona jeden
   argument:
     * EBX = 0, jesli chcemy otrzymac aktualny najwyzszy dostepny dla nas
       adres w sekcji danych. Te wartosc powiekszymy potem o zadany
       rozmiar pamieci.
     * EBX rozny od 0, jesli chcemy ustawic nowy najwyzszy adres w sekcji
       danych. Adres musi byc rozsadny co do wartosci i taki, by
       rezerwowana pamiec nie wchodzila na biblioteki zaladowane
       dynamicznie podczas samego uruchamiania programu.

   Jesli cos sie nie udalo, sys_brk zwroci -1 (i ustawi odpowiednio
   zmienna errno) lub tez zwroci ujemny kod bledu.

   Oczywiscie, argument funkcji moze byc wiekszy (alokacja) lub mniejszy
   (zwalnianie pamieci) od wartosci zwroconej przez sys_brk przy EBX=0.

   Jak widac, teoria nie jest skomplikowana. Przejdzmy wiec moze do
   przykladu. Ten krotki programik ma za zadanie zaalokowac 16kB pamieci
   (specjalnie tak duzo, zeby przekroczyc 4kB - rozmiar jednej strony
   pamieci - i udowodnic, ze pamiec rzeczywiscie zostala przydzielona) i
   wyzerowac ja (normalnie zapisywanie po nieprzydzielonej pamieci
   skonczy sie zamknieciem programu przez system).
   (przeskocz program)
; Dynamiczna alokacja pamieci pod Linuksem
;
; Autor: Bogdan D., bogdandr (at) op.pl
;
; kompilacja:
;
; nasm -f elf -o alok_linux.o alok_linux.asm
; ld  -o alok_linux alok_linux.o


section .text
global  _start

_start:

        mov     eax, 45         ; sys_brk
        xor     ebx, ebx
        int     80h

        add     eax, 16384      ; tyle chcemy zarezerwowac
        mov     ebx, eax
        mov     eax, 45         ; sys_brk
        int     80h

        cmp     eax, 0
        jl      .problem        ; jesli blad, to wychodzimy i nic sie
                                ; nie wyswietli

        mov     edi, eax        ; EDI = najwyzszy dostepny adres

        sub     edi, 4          ; EDI wskazuje na ostatni dostepny DWORD
        mov     ecx, 4096       ; tyle DWORDow zaalokowalismy
        xor     eax, eax        ; bedziemy zapisywac zera
        std                     ; idziemy wspak
        rep     stosd           ; zapisujemy caly zarezerwowany obszar
        cld                     ; przywracamy flage DF do normalnego stanu

        mov     eax, 4
        mov     ebx, 1
        mov     ecx, info
        mov     edx, info_dl
        int     80h             ; wyswietlenie napisu

.problem:

        mov     eax, 1
        xor     ebx, ebx
        int     80h



section .data

info            db      "Udana alokacja pamieci.", 10
info_dl         equ     $ - info

   Spis tresci off-line (klawisz dostepu 1)
   Spis tresci on-line (klawisz dostepu 2)
   Ulatwienia dla niepelnosprawnych (klawisz dostepu 0)
