Aký bol vlastne dôvod zavedenia segmentácie s tým bizarným prekryvom? Ak by boli segmenty bez prekryvu (tzn. výpočet efektívnej adresy DS << 16 | DX) a existovali by inštrukcie pre aritmetiku nad pármi seg:offs registrov (ideálne vrátane blokových), kompatibilita s 8080 kódom by zostala zachovaná v podobnej miere, aj tiny/small modely by fungovali rovnako úsporne, no zároveň by sa dal výrazne príčetnejšie písať kód operujúci mimo hraníc 16b adr. priestoru. V princípe by to bolo analogické riešenie k 8-bitovým CPU so 16b adresovaním pármi 8b registrov.
3. 6. 2025, 16:25 editováno autorem komentáře
IMHO Intel o tom moc nepřemýšlel a rozšířil možnosti CPU 8085 (to je taková lepší 8080). Kdyby to bylo, jak píšeš, bylo by to super, protože by od začátku mohla být paměť s 32bitovou adresou - něco co neuměla ani 68000.
Jedinej důvod, který mě napadá, je ten, že takto se nemusí použít celých 64kB například na zásobník, ale může to být fine-tunovatelné po 16 bajtech. Jinak je to celý špatně :-)
Ten pár registrů z 8-bitů moc efektivní není, bo musí přepočítat oba registry. U těch x86 segmentů se naopak dá paměť rozdělit na dostatečně malé kousky, aby jakákoliv struktura začínala na offset 0 a posun v poli mění jenom jeden registr.
Ono to v zásadě nějak stačilo docela dlouho. Peklo pak bylo adresování ve VGA, ale VGA přišla až po 32-bitové i386 . To, že byl 16-bitový DOS majoritní systém ještě 10 let po uvedené i386, je jiná pohádka. Tím nechcu říct, že to byl dobrý design...
Ohledně 68000 - ta právě uměla 32-bitové adresy od začátku, ne? (pominu-li fyzické limity)
Pohybovat segment o 16 bajtu ti umozni mit zarovnane 64k pole s ofsetem od nuly. A prijdes max o 15 bajtu na vypln.
Tvuj navrh vyzaduje komplikovane vypocty pro kazdy pristup do pole. Nebo umet nejakou instrukci [SEG:OFS]+n*INDEX.
Tvuj navrh ma problem s tim ze kdyz nebude pole zarovnane, tak klidne muze zacinat s OFS 64K-100. Takze po 100 bajtech musis zvednout SEG. Nemuzes pouzivat OFS snadno jako INDEX. Jedine ze to zarovnas, ale to mas jen 16 moznosti pro megabajt.
Museli by obetovat neco pro budoucnost, v dobe kdy tam maji 20 pinu. Takze bys kupoval v dobe co procesor byl drazsi nez clovek jen omezenejsi verzi co meli.
Proste to lepili jako snehovou kouli, nebo jako kdyz privaris k autu autokaravan, a pak dalsi jeste vetsi a dalsi. Pokud by tam nebyl ten predchozi a rovnou presli na vetsi tak by to mohlo vypadat jinak...
Nejakej smysl to davat muselo. Hlupaci to nebyli. .)
3. 6. 2025, 18:53 editováno autorem komentáře
Jj, pravda, umožňovalo to mať de facto kdekoľvek v 20b adresovom priestore 64k štruktúru, lacno adresovateľnú jedným 16b registrom. To je v situácii s jedinou 16b sčítačkou vcelku hodnotný benefit (ale za cenu skomplikovania rozšíriteľnosti do budúcna). Pre porovnateľne rýchle adresovanie v tom druhom prípade by to chcelo širšiu než 16b sčítačku.
3. 6. 2025, 20:44 editováno autorem komentáře
(resp. takto je realizovateľné úplne bez sčítačky, len bitwise operáciami niečo, čo by v tom druhom prípade vyžadovalo buď sčítačku, navyše >16b pre random access, alebo špecificky písanú logiku s podmieneným kaskádovým inc/dec pri slučkách, prípade hw implementáciu rep inštrukcií, ktorá by to zahŕňala)
Scitacky su v tom procesore (minimalne) dve. Jedna v generatore adries a druha v ALU. Scitacka sa da spravit tak, ze bude mat nizku latenciu kvoli carry, takze to az taky problem nie je. Procesor ma zaroven tiez iba jednu adresnu zbernicu nie nejakej velmi valnej rychlosti, takze viac scitaciek v generatore adries nepotrebuje.
Ze generovanie adresy bez scitacky iba maskovanim nie je uplne super napad ukazuju jednotky MPU v mikrokontrolleroch, ktore casto taky pristup pouzivaju na definiciu regionov.
Aby sa procesor vyhol nutnosti mat scitacky v jednotke MPU, definuje region podobne ako masku siete - bity bazovej adresy regionu, ktore spadaju do jeho tela musia byt nulove. To ale vynucuje, ze kazdy region musi byt zarovnany na adresu rovnu alebo vacsiu velkosti regionu, ktora zaroven musi byt mocninou 2.
To setsakra komplikuje alokaciu pamate, pretoze staci, ze region narastie o par bytov z 254 na 257 bytov a kludne sa moze stat, ze sa cely region musi presunut na ine miesto.
TL;DR: Uspora pamate a rozsahu registrov.
V tej dobe (1980s) bolo ovela dolezitejsie setrit pamatou, nez podporovat velky adresny priestor. 16MB RAM v tej dobe mohlo stat gazilion penazi. Vacsina PC v tej dobe nebola osadena ani plnymi 640kB RAM s ktorymi ten model v pohode dokazal pracovat.
Ak by segmentove registre pracovali s granularitou 64kB, vznikne jeden z dvoch problemov:
- Bud budem plytvat vsetkou RAM medzi koncom poslednych dat v predoslom segmente a zaciatkom noveho segmentu
- Alebo pridem o rozsah (max. 64kB) indexovacich registrov tym, ze data naalokujem na nenulovom offsete v ramci segmentu.
- Alebo navyse este zabezpecim vacsiu nez nutnu fragmentaciu pamate, pretoze okrem toho, kde su obsadene miesta v pamati musim pri alokacii blokov zohladnit aj to, kde su hranice segmentov. 32kB volny blok na konci jedneho segmentu a 32kB volny blok na zaciatku hned dalsieho segmentu sa proste v takom systeme nedaju naalokovat ako jeden 64kB blok, lebo to nejde rozumne zaadresovat.
Riesenie s prekryvajucimi sa segmentami poskytuje slusnu granularitu 16 bytov pri sucasnom maximalnom rozsahu indexovacich registrov 64kB.
Pre 8086tku a dajme tomu aj 286tku to bolo zitelne riesenie. Na 386tke uz spravili v Inteli tu chybu, ze dovolili subezne pouzivanie segmentacie a strankovania.
Ad: Ak by segmentove registre pracovali s granularitou 64kB, vznikne jeden z dvoch problemov
:
preto som tam explicitne uvádzal tú druhú premisu "... a existovali by inštrukcie pre aritmetiku nad pármi seg:offs registrov (ideálne vrátane blokových [prenosov])"
Čo by umožňovalo de facto lineárne adresovanie bez ohľadu na hranice segmentov. Všetky adresovacie režimy vyžadujúce sčítanie offsetov (MOV AX, [BX+n]; MOV AX, [SI+n]; MOV AX, [BX+SI]; MOV AX, [BX+SI+n], REP ...) by museli byť samozrejme realizované tak, aby si pri pretečení/podtečení offsetu vedeli korektne inkrementnúť/dekrementnúť aj segment.
No, to znie pekne len do momentu, kym si clovek uvedomi, ze napr. taku dvojicu 8 bitovych registrov slo v instrukcnej sade 8080 pouzit ako jeden 16-bitovy register iba v doslova par instrukciach. A neslo pouzit hocijake dva registre, ale iba konkretne dva registre.
Tam to malo svoj dovod - zjednodusilo to zapojenie procesora a vsetky vypocty adresy musel robit software. Spocitanu adresu potom slo priamo vystavit na adresnu zbernicu. Samozrejme to ale bolo pomale.
x86tka trpela na maly pocet registrov uz aj bez toho, takze by toto riesenie bud muselo fungovat na viacerych dvojiciach registrov, alebo by bolo zbytocne zlozite do tej miery, ze priame pouzitie 32-bitovych registrov by uz bolo jednoduchsim riesenim.
Nie je to priamociare, ale zbytocne komplikovane.
No v rámci 16b architektúry je to priamočiare riešenie, keďže to umožňuje ponechať drvivú väčšinu CPU 16-bitovú, bez potreby ťahania širších interných zberníc a nárastu množstva tranzistorov. Širšie musí fungovať len minimálna časť, týkajúca sa adresovania. To je dosť podstatný aspekt, čo sa týka nákladov (v čase vzniku). Plus teda to širšie adresovanie museli riešiť tak či tak, akurát zvolili riešenie 1. natvrdo, bez rezervy našité na 20b adr. zbernicu a 2. hodne komplikujúce kód operujúci na širších než 64k štruktúrach resp. štruktúrach ležiacich naprieč segmentami.
A čo sa týka 8080 a inštrukcií so 16b operandami, Z80 možnosti v tomto smere hodne rozšíril.