pytanie o stos (x86)

0

dlaczego systemy operacyjne przydzielaja stos?
To jest moja sprawa czy bede z niego kozystal, i tylko ja moge pilnowac by nie przekroczyc jego dolnej granicy. Dlaczego dajmy na to windows wymaga stosu do przekazywania argumentow? A wersja 64bitowa to juz <ort>w ogóle </ort>porazka, ale o tym pozniej.

Jak system mi alokuje stos, to:

  • rezerwuje czesc przestrzeni adresowej
  • mapuje pamiec pod kilka najwyzszych stron
  • kolejna nizsza strone oznacza jako guard page
  • ustawia XSP na najwyzszy bajt

ja zaczynam swoj program, i chce wywolac api, dajmy na to HeapCreate().
wiem tylko tyle ze ss:xsp zawiera adres stosu.
moge uzyc instrukcji push zeby przekazac argument, i call by wywolac funkcje.
do tego momentu wszsytko jest znosnie. Jesli skonczy mi sie stos, odwolam sie do strony ktora jest oznaczona jako non-present, i page fault sprawdzi czy ma ja traktowac jako guard page czy nie, i zaalokuje mi wiecej stosu, lub przekaze wyjatek. No i oczywiscie po sobie nie posprzata (sprawdzone, odwolania do wyzszych adresow stosu nie dealokuja juz przydzielonej pamieci).
Wiec jedyne co trace to pamiec.

Funkcje natomiast lubia tworzyc sobie pamiec poprzez odelmowanie od SP, albo instrukcje enter.
pojecie strony pamieci nie jest istotne dla programu, tylko dla systemu. tak na dobra sprawe to strona moze miec tylko 1 bajt a program musi dzialac jak by miala 1 gigabajt.
mechanizm guard page dziala tylko jak odwoluje sie do stosu elementarnie, push/call/int.
co jesli uzyje sub esp,32?
program przejedzie guard page i lezy. jest jeszcze instrukcje enter ktora rzuca page faulta jesli zapis pod nowy SP by spowodowal go, ale nic nie stoi na przeszkodzie by nowy sp wskazywal na inne dane. guard page jak alokuje ostatnia strone to nastepna chyba zawsze jest oznaczona jako nonpresent, wiec pushami czy nigdy nie wjade w inne dane.

dlaczego to OS decyduje o tym ile stosu ma moj kod?
dlaczego funkcje api wymagaja stosu? co stoi na przeszkodzie by ufnkcje ktore wymagaja pamieci nie alokowany jej sobie same, tudziez nie wymagaly jej od usera ze wzgledu na wydajnosc (dokumentacja by mowila ile pamieci masz jej przekazac)?

User wtedy by tworzyl wlasny stos, i wiedzial ile jeszcze elementow moze na niego wrzucic.

Co o tym myslicie?

0

Nie OS decyduje, tylko Ty ustawiasz w linkerze ile chcesz mieć stosu reserved i commit. Jeżeli zapiszesz ponad poziom commit, to automatyczny pagefault handler doalokuje tyle pamięci, ile trzeba, nie przekraczając ilości stack-reserve minus SetThreadStackGuarantee.
Gdy pomimo tego zabraknie stosu, to zawsze można doalokować większy blok pamięci, i odpowiednio zmienić xSP i 3 pola w TEB, dotyczące stosu (żeby SEH działał).

Dlaczego funkcje api wymagaja stosu? Bo alokacja stosu jest o wiele wydajniejsza od heapu, wystarczy zmniejszyć jeden rejestr, nie tracąc czasu na kopanie w strukturach by znaleźć odpowiedni wolny blok pamięci.
Uruchamiając funkcję, procesor musi zapamiętać gdzie ma wznowić pracę po powrocie. Gdyby nie było stosu, to niby gdzie miałby to zapamiętać? Gdyby było tylko jmp, bez call, to programista sam by wpadł na pomysł, by zrobić sobie stos.

0

Dobrze, ze odblokowales, bo juz chcialem temat o to pisac.

Dlaczego dajmy na to windows wymaga stosu do przekazywania argumentow?

Jak dasz funkcje jako __fastcall to jej dwa pierwsze argumenty ida przez rejestry.
Z tego co pamietam pierwszy przez ecx, a drugi przez edx. Natomiast, jesli taka funkcja ma wiecej niz dwa argumenty to juz na stos ida, ale nie jest konieczne w wysokopoziomowym kodzie przekazywac parametrow przez stos. Na niskim poziomie sam decydujesz jak beda przekazywane parametry.

Wiec jedyne co trace to pamiec.

Nie jest powiedziane, ze musi byc wyjatek jak stos sie skonczy, poniewaz moze zostac
kolejna strona zaalokowana na jego potrzeby. A z tym esp i ss glupoty napisales.

Funkcje natomiast lubia tworzyc sobie pamiec poprzez odelmowanie od SP, albo instrukcje enter.

Instrukcja enter to sa po prostu dwie instrukcje push ebp i mov ebp, esp, wiec nie wiem
w jaki sposob pamiec mialaby byc tu przydzialana oprocz tego, ze esp po push'u zostaje
zmniejszone o 4.
Funkcje odejmuja od esp, aby zaalokowac pamiec na swoje zmienne lokalne, poniewaz pamiec pod esp NIGDY nie moze zostac uzyta, poniewaz jest uznawana za juz nie wazna i na tym wlasnie polega cala idea ramek stosu i tego odejmowania. Dochodzi jeszcze to o czym Sapero napisal, czyli szybszy dostep do stosu nic do heap'u.

pojecie strony pamieci nie jest istotne dla programu, tylko dla systemu. tak na dobra sprawe to strona moze miec tylko 1 bajt a program musi dzialac jak by miala 1 gigabajt.

Zaznaczyles na poczatku, ze mowimy o systemie Windows na architekture 32 bitowa, wiec
skad wzial Ci sie rozmiar 1 bajta. Strona zajmuje tutaj 4kB. Dalej nie lapie o co Ci chodzi z ta ochrona stron i stosem.

dlaczego to OS decyduje o tym ile stosu ma moj kod

Sam decydujesz. Po prostu jesli Ty nie zdecydujesz to system wybiera domyslna wartosc, wiec
nie masz sie czemu dziwic, ale jesli sam sobie okreslisz to bedziesz mial wiecej.
Na Linuksie poleceniem ulimit mozesz zwiekszyc standardowy rozmiar stosu.

dlaczego funkcje api wymagaja stosu? co stoi na przeszkodzie by ufnkcje ktore wymagaja pamieci nie alokowany jej sobie same, tudziez nie wymagaly jej od usera ze wzgledu na wydajnosc (dokumentacja by mowila ile pamieci masz jej przekazac)?

Wymagaja, bo tak sobie autorzy wymyslili, ze wiekszosc funkcji winapi bedzie __stdcall i nic nie
stoi na przeszkodzie abys sobie podmienil api na wlasne, czy sam system napisal. Tylko wtedy
bedziesz pisal kod, korzystajac z wlasnych funkcji, o ktorych nikt nawet nie bedzie slyszal.
Co stoi na przeszkodzie ? Moze to, ze jak nie zaalokuja pamieci to nie beda mialy tej pamieci, wiec
zmienna w pamieci sama w sobie straci racje bytu, chyba ze wszystko bedzie na dysku zapisywane, co
oczywiscie byloby glupota ze wzgledu na wolniejszy czas operacji dyskowych niz pamieciowych.

0
t0m_k napisał(a)

Dobrze, ze odblokowales, bo juz chcialem temat o to pisac.

To najśmieszniejszy/najżałośniejszy post gościa znanego jako h3x, haker-wannabe potrafiący głównie [CIACH!] od rzeczy i unikać korzystania z dokumentacji. Wątek pierwotnie trafił do Perełek aby zachować dla potomności, ale przez cyrki z bazą zaczął figurować w dwóch działach, pojawiła się odpowiedź sapero, cofnąłem.

Sam nie wiem czy trolluje czy pyta na poważnie, po jakichś czterech latach masturbowania się assemblerem... Od tego momentu się w wątek nie mieszam.

Ciekawie wyglądałby system operacyjny pisany w CPS, tam można się bez stosu obyć, ale na wykorzystanie kontynuacji (i closures) autor wątku zwyczajnie za kiepsko kombinuje.

0
deus napisał(a)
t0m_k napisał(a)

Dobrze, ze odblokowales, bo juz chcialem temat o to pisac.

To najśmieszniejszy/najżałośniejszy post gościa znanego jako h3x, haker-wannabe potrafiący głównie [CIACH!] od rzeczy i unikać korzystania z dokumentacji. Wątek pierwotnie trafił do Perełek aby zachować dla potomności, ale przez cyrki z bazą zaczął figurować w dwóch działach, pojawiła się odpowiedź sapero, cofnąłem.
Sam nie wiem czy trolluje czy pyta na poważnie, po jakichś czterech latach masturbowania się assemblerem... Od tego momentu się w wątek nie mieszam.

Nie chcialem, zebys cofal bo napisal madre rzeczy :D Chodzilo mi o to, ze moze sie zrobic ciekawa dyskusja z tego, a sam przyznasz, ze rzadko sie trafia temat odnosnie asemblera, czy architektury x86, wiec fajna odmiana, a w dodatku dla mnie interesujaca.

1 użytkowników online, w tym zalogowanych: 0, gości: 1