mam k tomu dotaz,celou dobu ziji v tom ze 32bit x86 v chranetem rezimu umi adresovat tusim 64TB pameti, 4GB je jen limit jednoho segmentu. ruzne OS s 4GB limitem jsou jen produktem nekoncepcnosti a "lenosti" tvurcu,ze nevyuzivaji naplno virtualizaci/segmentaci pameti. uznavam,kolem problematiky pmode a adresace jsem nikdy nic nedelal,takze vychazim jen z literatury,takze...jak to teda je? nejde mi to nejak pres nos.4 GB jsem do ted videl jako limit vel;okosti segmentu,takze pri dobre udelanem OS je to limit na souvisle alokovane pole v jednom kuse....
Žádný 32-bitový operační systém nepoužívá poitnery se segmentací. Kdybys chtěl použít segmentaci, tak bys musel pointer rozšířit z 32 na 48 bitů. Nahrávání toho segmentového registru je pomalé (6 - 20 tiků na různých procesorech), takže kdybys použil segmentaci na přístup k obyčejným datům, tak bys každý přístup do paměti zpomalil o tento počet tiků.
Pokud se segmentace používá, tak jen v případech, kdy není třeba ty segmentové registry pořád přepínat, např. na thread-local-storage (v userspace) nebo CPU-local-storage (v kernelu).
Pouze 16-bitové prostředí používají segmentaci. Tam by to bez segmentace nešlo, bez segmentace by člověk měl max 64kB dat.
16-bitové kompilátory mají možnost zvolit model (tiny, small, medium, compact, large, huge), který určuje, jak moc je program velký --- zda tam mají být 16-bitové pointery nebo 32-bitové pointery segment:offset na funkce a na data. Ve větším modelu může být větší velikost programu nebo dat, ale zase to běží pomaleji kvůli tomu, že se s každým přístupem do paměti nahrávají ty segmentové registry.
s tim uplne tak nesouhlasim.z aplikacniho hlediska,i kdyby mel jeden proces code=data=stack rozhodne by mel kazdy 4gb jen pro sebe.navic int far *ptr v nekterych rozsirenich C jeste na 16bitech bylo,nebyl by problem s tim delat na 32bitech.me se proste nelibi,ze se vubex nevyuziva velka cast toho co architerkura nabizi, na x86 HDT/LDT tabulky+ 4 urovne opravneni (pokud si to pamatuju dobre) jsou dobre hw prostredky pro navrzeni schopneho bezpecneho OS
Ono si tim totiz clovek az tak moc nepomuze, protoze segmenty se stejne nakonec mapuji do 32bitove linearni adresy.
Asi by se dalo predstavit, ze operacni system vyrobi vice deskriptoru nez se do adresniho prostoru vejde s tim ze jenom nektere budou present a pak bude odchytavat Segment Fault (intelovina, nesouvisi se SEGV) pri mov cosi,%ds a v tabulce stranek nejaky odpovidajici kus stranek prohodi aby ukazovaly na jine fyzicke adresy a deskriptor zpristupni. Nicmene nema to moc smysl, protoze aplikace ktera potrebuje hory pameti muze vicemene totez delat v userspace (v linuxu vyrabenim souboru v /dev/shm a mmapem, windows na to dokonce maji jakesi funkce primo pro to urcene). Pokud by to delal OS celou situaci jeste komplikuje to, ze by na to nekdo musel napsat kompilator, ktery s tim pocita.
Teoreticky by sa nemuseli az tak casto prehadzovat. Kod moze byt vo vlastnom segmente 4GB (CS), zasobnik SS, na najcastejsie data DS, a na ostatne niekolko 4GB segmentov (ES,FS,GS), splu teda 16 GB data + 4GB stack, keby sa vyuzivala segmentacia. Je ale pravda ze by sa to horsie programovalo, chcelo by to nejako logicky rozdelit data do segmentov tak, aby nebolo treba vsade pouzivat segmentove pointre. ( 4 heapy)
To by pak už nešlo programovat v C. V C může tentýž pointer ukazovat na read-only data, na read-write data, na zásobník nebo na haldu (nebo i na funkci ... ale ten nemůžeš dereferencovat, pouze volat). A když bys ten pointer dereferencoval, tak bys musel rozhodnout, kam ten pointer patří a podle toho použít segmentový registr.
Buď bys to testoval automaticky ve vygenerovaném kódu --- to by ti zpomalovalo každé hrábnutí do paměti přes pointer.
Nebo bys musel programátora nutit, aby ke každému pointeru určoval, do jakého segmentu patří --- a pak by ti na tom obyčejné C programy nechodily.
Třeba by to šlo programovat ve starém Fortranu (nemá pointery vůbec) nebo v původním Wirthově Pascalu (má pointery, ale nejde tam pointerem ukazovat na jiné proměnné nebo pole, pouze na haldu; ukazování pointerem na proměnné tam přidal snad až Borland v jejich Turbo Pascalu).
Třeba OS/2 v kernel módu má odlišnou bázi SS a DS segmentu. Má to blbý důsledek, nejde tam napsat něco jako void f() { int X; int *P = &X; ... } --- protože do P se uloží adresa vůči SS segmentu, ale v momentě, kdy se to dereferencuje, tak se použije segment DS --- takže v momentě, kdy se odkaz na zásobník v kódu vyskytne, musí se ten kód ručně upravovat a musí se k tomu uměle přičítat rozdíl DS a SS bází.
Čtyřmi segmentovými registry DS,ES,FS,GS vlastně stejně současně nenaadresuješ 16GB. Každý z nich má totiž pouze 32-bitovou bázi a délku. Jediná možnost, jak byses přes těch 4GB dostal, by bylo, že bys opravdu musel při každém přístupu do paměti nahrát segmentový register a při výpadku segmentu jiný segment odmapovat, abys pro nový segment udělal místo v tom 4G rozsahu.
Zacnem od konca. No je uz moc hodin a nestudoval som PAE, neslo by tie segmenty vyriesit cez PAE?
A tiez len som si matne spomenul ze nieco sa so segmentami riesi aj v C cez pragmy. Idem uz spat, tak len nadhodim priklad #pragma data_seg(".my_data1")
... ze by spravit si takto segmenty a dat tam napr. velke staticke polia. Jeden pointer co by mohol obsahovat adresu hociktoreho segmentu by sa nedal spravit, ale to v podstate ani nemusi byt potrebne pri aplikaciach co si vedia rozne typy dat rozdelit do segmentov.
Ne. Překlad adresy je: virtuální adresa (14bit segment+32bit offset) -> lineární adresa (32bit) -> fyzická adresa (36bit). Úzké hrdlo je zde ta lineární adresa. Takže v jednom okamžiku procesor bez přepínýní segmentů nebo stránek naadresuje pouze 4GB, víc nemůže.
Ad to umisťování proměnných do samostatných segmentů --- dají se takto umístit proměnné, na které nemůže vést pointer. Nebo pak při dereferenci pointeru nahrávat segmentový registr.
Více segmentů v C lze použít, akorát ten pointer musí být typu long long (64 bitů) a nést tak s sebou i informaci o segmentu. V jednom pokusném OS, jenž jsem spoluvyvíjel, jsme to tak měli, ale segmentaci jsme používali pro její původní účel, tzn. rozdělení přístupových práv k paměti, ne pro mapování více než 4 GiB.
Ale žádný 32-bitový kompilátor long long pointery nemá. Pak leda zbývá si takové pointery emulovat přes makra preprocesoru a inline assembler. A když na to budeme přistupovat přes vlastní makra, tak můžeme zapomenout na provozování obecného C kódu napsaného někým jiným.
Segmentace je sice 46bitová, ale mapuje se na 32bitovou logickou adresu, která se stránkuje (a ta přes PAE může mít až 51 bitů). Ta 32bitová logická adresa, která je společná pro všechny segmenty, je to omezení na 4 GiB. Šlo by to sice řešit zneplatněním segmentů a přehazováním logické adresace při přístupu k takovému segmentu, ale to by bylo dost pomalé.