Építsünk virtuális gépet?

Fórumok

Észrevettem, hogy jobbára amatőr fejlesztői körökben a compilereket, fordító-programokat kisebb fajta misztikum övezi. Feltételezem a beléjük képzelt bonyolultságuk, "áttekinthetetlenségük" okán. A nyelvek közül az assembly is hasonlóképpen túl van misztifikálva.

Arra gondoltam, hogy ezt a helyzetet oldhatnám, ha lépésről-lépésre bemutatnám egy szimpla, végletesen redukált utasításkészletű virtuális processzor [VCPU] felépítését. Még hozzá, a tervezés lépéseitől a megvalósításig, valamint egy, a VCPU-hoz tartozó nagyon egyszerű assemblert, szintén annak tervezésétől a megvalósításáig, néhány lépésben.

Maga a VCPU roppant egyszerű (kb. 300 sor kód), mindössze tíz utasítást lenne képes végrehajtani. Ezek elsajátítása gondolom nem okoz különösebb nehézséget azok számára, akik érdeklődnek efféle dolgok iránt. Az egész "virtualizáció" tulajdonképpen alig lenne több egy CASE utasításnál. Az assembler is a végletekig egyszerűsített, bár valamivel összetettebb lenne mint a VCPU, de ez is alig 3-400 sornyi kód, 10-12 függvény, ami bemutatná azokat a fázisokat, amelyen keresztülmegy a bemenet, a forrás, amíg végül futtatható binárissá nem lényegül.

Ha van a dologra érdeklődő, akkor szívesen megírom a körítést, a magyarázó szöveget és publikálom is a forrással együtt, mert maga a VCPU és annak assemblere már évek óta készen van.

Értőbbek számára:
A VCPU egy munkaregiszteres /ez az ACCU, és mindössze 8 bit széles/.
A VCPU-hoz kapcsolódó memória maximum 256 byte. Címzésmódja lineáris.
Aritmetikai utasítások operandusai: az ACCU és egy memóriacím tartalma. Az eredmény mindig az ACCU-ban tárolódik.
A VCPU (a maga korlátain belül (memória mérete)) turing teljes. 
Használata: A VCPU az assemblált "binárist" beolvassa a memóriába, majd rákerül adott címre [org] a vezérlés. A program lefut, minden CPU állapot és memóriatartalom formázottan, szekvenciálisan egy kimeneti file-ba (.html) íródik. Ezt a file-t lehet analizálni.

[Igaz, van egy interaktív megvalósítás is, lépésenkénti programvégrehajtással, backstep lehetőséggel, stb. de oktatási célokra a .html-es verzió szvsz alkalmasabb]  

Szóval?
Vélemények, hozzáfűzni valók, javaslatok, ellenvélemények, kérdések?
Minden kommentet szivesen fogadok, ha  tartalmilag érdemes, akkor hasznosítom. 
Köszönöm előre is. 

Hozzászólások

Én örömmel várnám és tanulnék belőle.

Szeretem az ilyesmit, szívesen elolvasom amit írsz. Véleményem az persze van: szerintem legyen az a 256 nagyobb, semmivel nem lesz bonyolultabb semmi, de legalább alkalmas lesz valódi feladatokra is az eredmény. Például lehet 32 bites a regiszter, és 4GB a RAM.

Én is elkezdtem egy nyelv fejlesztését, de más absztrakciós szinten dolgoztam vele: JVM-hez hasonlót terveztem, az kicsit más.

Szerintem jöhet. Angol nyelven rengeteg ilyen van, de egy normálisan összeszedett magyar nyelvű szerintem még nincs ;)

// Happy debugging, suckers
#define true (rand() > 10)

Én támogatnám a 256 bájtot, úgy egyszerűen lehetne vizuálisan is megjeleníteni a teljes gépállapotot.

(Az ilyen egyszerű gépről mindig a memóriaháború jut az eszembe. Talán azt is lehetne vele futtatni, már ha van benne megszakítás.)

Ha jól megy és sok embernek tetszik, akkor a CPU-dat elkészítem Verilogban, aztán mehet FPGA-ba..

Lehet a témát azzal kezdeni, hogy
   - Harward elvű
   - Neumann elvű
   - vagy verem bázisú (lásd Forth és társai ... szoftveres emulációban gforth, dc)
legyen?
Legyen külön I/O utasítása vagy memória címtartományba ágyazott I/O?
Előnyök, hátrányok ... melyik egyszerűbb felépítésű?
 

érdekel, örömmel vizsgálgatnék egy ilyet

Szerkesztve: 2020. 12. 08., k – 14:20

Nagyon  köszönöm minden kedves érdeklődőnek a roppant pozitív megnyilatkozást. Minden várakozásomat már most felülmúlta a hozzászólások száma és hát, a tartalmuk szintén.

Próbálok választ is adni a felmerült igényekre, kérdésekre, kérésekre:

- Igen, lefelejtettem /pedig fontos/ hogy Von Neumann elvű a masina. Memóriába ágyazott I/O. Pszeudo stack.
- Nem verem alapú, tulajdonképpen egy "kvázi regiszteres" gépről beszélhetünk. 
- A memória egyelőre csak 256 byte marad, ahogy plt rá is mutat, a vizuális megjelenítés okán lett ilyenné és azt hiszem így maradt igazán oktatható, megérthető. De alapban 64 byte memóriával lesz kiépítve, így ugyanis több tartalom /step/ fér el egy oldalon. A memó mérete egyébként egy konstans átírásával egyszerűen módosítható.
- Ebben az első verzióban nincs megszakítás, még flag sem, de a következőben lesz. Eredetileg ez az anyag egy nyomtatásban megjelentetni szándékozott könyv appendixe lett volna, sok egyéb mellett. A cím beszédes: Hogyan írjunk compilert, interpretert, virtuális gépet. A könyvet viszont már megírni nem fogom, ezért is gondoltam, hogy a létrehozott anyagokat azokkal osztom meg online, akiket ez a téma szívből érdekel.
- Mind a vCPU mind az assemblere szándékosan úgy van megírva, hogy abszolút "basic" nyelvi elemeken kívül másból nem áll. Nincs semmiféle virtuózitás, még pointerek sincsenek. Az elsődleges cél az egyszerűség és érthetőség volt. Már az követni, reprodukálni, netán még bővíteni is tudja a vCPU-t és az assemblert is, aki az abszolút alapokkal (változó tipusok, elágazás, iteráció, file I/O) tisztában van. 
A legtöbb munkát éppen az egyszerűsítés, a karcsúsítás igényelte. :o)
I/O utasításokkal együtt a HALT-on kívül mindössze kilenc utasításra épül minden. De persze bővíthető kedv és igény szerint, ráadásul nagyon egyszerűen. Ezt majd be fogom bizonyítani.
 

A halt a CPU-t állítja meg. Nem valódi megszakítás, csak akkor "következik be" ha a következő memóriacímet MEM[IP] olvasva a gép 00h-t talál.
RISC ez a CPU már magában attól is, hogy csak 10 utasítása van. Az alapötlet a PDP8-ból származik, annak is csak 8 utasítása volt. Az utasítások száma, hogy most 8 vagy 10, nem lényeges. 

- Elbandi - Endianness. A fentebb említett, immár soha el nem készülő könyv anyaga úgy készült, hogy első lépésben egy nagyon egyszerű gép felépítése és programozása kerül bemutatásra (erről írok a bevezetőben), majd ez bonyolódik, a gép idővel két regiszteresre, a memóriája "sok" KByte-ra, az utasításkészlete pedig a duplájára bővül*. Ebben a bővített verzióban már helyet kap az endianness és annak kezelése is, mivel a memória továbbra is byte-os szervezésű marad. 

* Ezt egy, bár egyszerű, de már magas szintű nyelven is lehet programozni.

 

A dinamikus (NMOS) processzorok ilyenkor szokotak lefagyni, azaz amnéziásak lesznek. Pl. a 8085 jelzi a "machine cycle status" kimeneten, ha haltban tartózkodik. Ekkor elengedi az összes ki- és bemenetét, és akár az ellenség is ráköltözhet a buszra. Mivel csak az interrupt működik, hát azzal lehet kiléptetni ebből az állapotból.

A statikus (CMOS) processzoroknál meg nincsen HALT. Ezen meg is döbbentem, de lévén szó mcu-ról kicsit más a működés, ráadásul nincs külső busz. A HALT általában nem állítja meg a processzort, helyette akár lehet egy "loop: goto loop" is. Ha meg a karod állítani, arra ott a sleep, amivel még jegesmacikat is is menthetsz. ;)

Szerintem meg nem. Z80 - ő dinamikus, NMOS - HALT-ban ciklikusan fetch-eli az op. kódot, mert az első gépi ciklus vége a DRAM refresh is egyúttal, az meg baj volna, ha elmúlna. A lábait bus request-re emeli fel, s a bus ack-kal jelzi, hogy rászabadulhat valaki más - praktikusan a DMA kontroller - a buszra.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Szerintem meg igen.

Ravasz módon én sem mondom meg mire gondoltam. :-D

Ha arra gondoltál, hogy az i8085 más mint a Z80, akkor igazad van. Ezért kapsz egy kakukktojást: NSC800 - Z80 bináris kompatibilis, CMOS, részben statikus és dinamikus, 8085 busz, de Z80 szerű HALT, de 8085 állapotjelzések, stb.

Kérlek, próbáld meg a kifogásolt szöveget az előzményeket is figyelembe véve, nem a környezetéből kiragadva értelmezni.

Egyébként, ettől függetlenül (!): egy szoftveresen megvalósított processzornál az van, amit a megvalósító akar. Egyetlen utasításkészletet, architekturális jellemzőt sem kötelező követni, implementálni.    

Ok, csatlakozom az előttem szólóhoz. ;)

Az első szólásom arra vonatkozott - mint idéztelek:

Ebben az első verzióban nincs megszakítás

Tehát igenis értelmezzem helyesen!

A nem valódi processzornál, ahol nincs megszakítás, csak nem valódi megszakítás (mégis van??)...Értem! Nem!

Jobb verzió: A virtuális processzornál nincs huzalozott interrupt, de van emulált. Az emuláció úgy történik, hogy az [IP]=HALT utásításon álldogáló virtuális processzor figyeli az [IP+1] bájtot. Ha ez nulla, akkor virtuális megszakítás érkezett a virtuális processzorba.

Ez például sokkal jobb duma lett vón, mint az álságos megszakítással ijesztgetni a népet. ;)

Mégegyszer fussunk neki: Ha nincs megszakítás, akkor minek a HALT? Ez volt a kérdés.

Mégegyszer fussunk neki: Ha nincs megszakítás, akkor minek a HALT? Ez volt a kérdés.

Azért a HALT, hogy megálljon a CPU (gyk., hogy ne kapjon órajelet). Ráadásul (feltéve, ha megengeded) statikusan, hogy megőrizze az állapotát, amennyiben a user vissza akarna lépni, mert létezik interaktív implementáció is, mint azt írtam korábban. Sőt, létezik legalább 12 féle módon implementálva, bár igaz, ezt korábban nem írtam. Azt viszont talán nem is kéne írnom, hogy ez nem egy x86 vagy 8085 emuláció.
Azt sem kéne Írnom - legalábbis szerintem -, hogy nem véletlenül tettem idézőjelek közé azt, hogy "következik be".  Fölösleges leírnod, hogy a HALT utasítás megállítja a CPU-t, ezt leírtam előtted én is, azt is, hogy a HALT utasítás nem megszakítás, hanem utasítás. Én hittem azt, hogy te hiszed megszakításnak, ugyanis a bugyuta kérdéseidből (RISC, utasítás bitszélessége) számomra ez következett.   

Jobb verzió: A virtuális processzornál nincs huzalozott interrupt, de van emulált.

Nem, ez rosszabb duma "lett vón". Egyrészt azért, mert nem lett volna igaz. Ugyanis azt nem véletlenül írtam, hogy az első, legszimplább megvalósításban nincs semmiféle megszakítás, de még flag sem. Az egész egy működőképes processzor demonstrációja, annyira leegyszerűsítve, amennyire csak lehet, hogy minél többek számára érthető legyen a működése.
Bocsáss meg, de én ezzel a mondanivalómat irányodban befejeztem, ha továbbra is kötözködni szeretnél valakivel, akkor keresned kell valaki mást.   

No, pont ezért van neve is, hogy ne kelljen körülírni: breakpoint

Nem is árulom el, melyik processzor ;) használ olyat, hogy az utasítás első bájtját lecseréli egybájtos debug breakpoint-ra. Avagy SWI (softvare interrupt - másik terminológiával), amely a hozzá tartozó vektort hívja. Ez pontosan megfelel a "processzor működése megszakad, és az user megnézheti az állapotát, vagy interaktívan beavatkozhat a működésbe".

Persze én csak kötözködök. :( Pedig azért van, mert mert a leírás és körülírások halmozata teljesen kaotikus a megszokott szakkifejezések keveredése miatt:

  • a HALT utasítás (instruction) - Ez egy std utasítás, amire a processzor felfüggeszti a működését. Ebből az állapotból csak egy külső esemény billentheti ki.
  • a megszakítás (interrupt), ami nem halt és nem breakpoint - A fent említett breakpoint is szoftveres megszakítással van kivitelezve. Ilyenkor az interrupt nem külső esemény hatására jön létre, hanem a processzor "dob magának" egy eseményt.
  • a "halts processor" - Ami nem utasítás, csak annyit jelent, hogy (valami) megállítja a processzort.

A fogalmak közül bármilyen processzorról is írják, rögtön lehet tudni a jelentését.

Olyan ez, mint egy régi történet, amikor egy kollégának magyaráztam a makefile elemeit. Nosza, le is cserélte az all: címkét minden: címkére. Aztán jött az anyázás, mert a hülye make nem értette. (Csak kötözködött.) :-D

Soha nem hallottam róla, de izgalmas. Sokkal több lába van, mint utasítása vagy bit-je (https://en.wikipedia.org/wiki/Signetics_8X300

Egy ennyire egyszerű processzort egy webassembly is tud emulálni és mindenen is fut... már csak az a kérdés maradt nyitva számomra, hogy mit írunk ebben, mi lesz a célszoftver vagy megoldás?

Nana!

Ez egy 16 bites risc processzor!

could fetch, decode and execute an instruction in only 250 ns. Data could be input from one device, modified , and output to another device during one instruction cycle

Tehát egy MOVE 4 fázisban ezt csinálja 250 ns alatt

  • (fetch)
  • input
  • maybe rotated any number of places
  • and/or masked to any length
  • output

Ehhez képest az NMOS 8085 (~8080) 4MHz effektív órajellel 4 órajel alatt hajtja végre a legrövidebb utasítást két regiszter közötti move, ami 1000 ns. A többi utasítás 7-13 órajel.

Az applications fejezetben elfelejtették megemlíteni a rakétairányítást. Tán ezért gyártják változatlanul a mai napig. ;)

Azért 4 órajel, mert 3-ig a memóriára vár, hátha annyira lassú.

A másik vonal (motorola és tsai) 1 MHz-n járt, az elég lassú volt a memóriákhoz, így 1 ciklus alatt elérte az adatot, a következőben feldolgozta, így egy nop is 2 ciklus lett.
Ott aztán lettek egész hosszú utasítások, ha memóriatartalommal végzett műveletet..

Mit hívunk magasnak? 20 MHz? -> 5 millió utasítás/másodperc? Netán ennek csak ötöde?
     https://ww1.microchip.com/downloads/en/devicedoc/35007b.pdf

Ha egyszerűsíteni akarod az architektúrát, kevés tranzisztorral akarod megúszni a gyártást, akkor ne csinálj pipeline feldolgozót, hanem egyszerű 4 fázisú szinkronfeldolgozót.

Azonos gyártástechnológián rövidebb utak általában  magasabb frekvenciát eredményeznek. Az hogy ez most abszolút 20 MHz vagy 3 GHz lényegtelen, mert a relatív érték számít. A legjobb eredmény (részben vagy egészen) aszinkron esetben lehetne, de annyi szívás van vele, hogy nem ismerek olyat, aki ilyen CPU-t tervezett volna.

Valamint minél kevesebb (és rövidebb) út van használva egyszerre, annál kevesebb általában az egység fogyasztása is, ami miatt szintén magasabb frekvenciát lehet alkalmazni (mert nem fog annyira melegedni és nem kell annyira hűteni).

Komolyan mondom, hogy egyetlen aszinkron processzor adatlapját olvastam, de nagyon régen volt, részletekre nem emléxem.

Az eredeti elképzelésed, amit hg2ecz megválaszolt a későbbiekben csúnyán "továbbfejlődött". A 8085 - amelyben néhol egy egy órajelnyit sikerült lecsípni a 8080 utasításihoz képest - bizony "nagyon szinkron" volt, míg a Motorola többet párhuzamosított a feldolgozáson. Ez a módszer annyira elharapódzott, hogy az Intel porcesszorok utasításai egyre inkább mikroprogramozottak lettek, néha fájdalmasan lassúak. Így a 8086 is szörnyű lassúra sikerült, mert pl. a bonyolultabb címzést ki kellett számolni, a shiftelést egyenként végre kellett hajtani, stb. Ennek egy ígéretes továbbfejlesztése volt a V20, ahol a mikroprogramozott funkciókat külön ALU vagy külön céláramkör végezte sok órajelet lefaragva a végrehajtási időből.  

Szívesen elolvasnám, ha megcsinálod. 

Nem tudom, hogy Ben Eater youtube csatornáját ismered-e ő valami hasonlót csinál, csak ő fizikailag valósítja meg, onnan is tudhatsz ötletet meríteni. 

Igen, ismerem Ben Eater munkáit. Ő hardverből építkezik, valami hasonló célzattal. Az én szoftveres CPU megvalósításom az övénél sokkal egyszerűbb, hiszen felhasználom hozzá azt, ami készen van és amit az alkalmazott programnyelv lehetőségei kínálnak. Szóval, az én dolgom könnyebb. ;)

Ha lesz még hozzá kedvem, akkor lesz disassembler is, bár egy idő után a memória tartalmából ki lehet olvasni és értelmezni a kódot. Ezt tapasztalatból mondom. Ráadásul ezt segíti az is, hogy az utasítások hexa opkódja amennyire lehet, idézi az utasítást, így a CMP /compare/ utasítás 'C0', Az ADD utasítás ami egy memóriacím tartalmát adja hozzá az accumulátorhoz, 'AA' /add to accu/. De a disassembler megírása kimerül úgy plusz húsz sorban. Úh. ezen nem fog múlni semmi. :) 

Eddig nekem ez a minimalista proci volt a minimum, amit láttam: https://github.com/cpldcpu/MCPU   - 32 makrocellás CPLD elég volt hozzá + memória. Ott van Verilog-ban és VHDL-ben is minden róla. Faék egyszerű demóalap.

Egyébként a verem bázisú az igazán minimalista, amit a mai napig használnak:
     http://fizikaiszemle.hu/archivum/fsz1610/FizSzem-201610.pdf   -  9. oldal jobb hasáb tetején megnézve a Philae üstökösre 3-szor is :) landoló egység prociját, RTX2010 ... sugárzásbiztos faék egyszerű, verem bázisú proci.
     Proci adatlapja: https://www.mouser.com/catalog/specsheets/intersil_fn3961.pdf - 31. oldaltól DROP OVER SWAP DUP

Egyébként a FORTH és a verem bázisú processzor fura jószág, nem csak a Philae üstökösre menő egység procijának lett verem bázisú proci választva, de sok rakéta tűzvezető rendszere is FORTH-ban implementálódott.

Aki nem ismerné, az alapok:
  - literál a programból/IO eljárásból --> verembe
  - literál a programból/IO eljásárból --> verembe
  - ...
  - ADD           ; veremből ki a két legfelsőt, összeadás, eredmény vissza a verembe
  - SWAP         ; verem két felső elemét felcseréli, hogy az utána következő osztás a/b helyett b/a-t számoljon.
  - DUP            ; verem legfelső elemét mégegyszer betolja a verembe
  - OVER          ; verem legfelső alatti elemét betolja (megismétli) a verem tetejére.
  - ROT            ; egyetlen felső 3 elemet érintő művelet ... legfelső 3 elemet megforgatja a veremben.
  - DROP          ; kiszedi és eldobja a verem legfelső elemét

$ echo "6 5 7 + SWAP / ." | gforth    # . a kiíró eljárás, a verem legfelső elemét kiírja.

Természetesen implementálva van I/O eljárás, hogy a verem legfelső elemét ki is tudd rakni például hardver portra, illetve a hardverportról be is tudj olvasni a verem tetejére.
Továbbá ciklus, eljárás, feltétel, ... létezik. Eljárást tudsz FORTH-ban definiálni a : jellel, ezzel új utasítást teremtve, ami a stackból kiemeli az adatot és végül a stackbe rakja vissza az eredményt.
Itt látható egy alap stack bázisú (FORTH) processzor Verilog-ban: https://www.excamera.com/sphinx/fpga-j1.html

A teljesség kedvéért: verem bázisú a Forth, Postscript, Factor.
Valakinek elgurult a gyógyszer, Forth-ban írt webes környezetet: https://www.1-9-9-1.com/

Itt a FORTH mellett meg erdemes azt megemlitenunk hogy a klasszik 8087-es lebegopontos proci utasitaskeszlete is teljesen hasonlo elven mukodik: https://hu.wikipedia.org/wiki/X87

míg a diadikus műveletek – FADD, FMUL, FCOM és mások – az ST(0) és ST(1) regiszterekkel végzik el a műveletet

... es a tobbi. Es ugye ezt orokolte a minden is ami az x86-sorozatbol szarmazik. 

Akinek volt anno ZX Spectruma, s tanulmányozta a BASIC interpreterén belül az aritmetikáját, az is találkozhatott a LIFO-n történő műveletvégzéssel. Ha jól nézem, amit írtál, print (5 + 7) / 6, azaz 2 lesz az eredmény. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Igen annyi. Egyébként erre kukk rá, birom ahogy 40 éve magyaráztak a könyvek: https://1scyem2bunjw1ghzsf1cjwwn-wpengine.netdna-ssl.com/wp-content/upl…  34. oldaltól.
 

Egyébként az előbbi gforth példa dc-vel is megvalósítható. Ennek az angol szavak helyett 1..2 karakteres nyelvezete van:
   $ echo "6 5 7 + r / p" | dc         # bővebben: man dc illetve https://en.wikipedia.org/wiki/Dc_(computer_program)

Van egy ilyesmi könyv is -- angolul -- a hozzá való szimulátorral, feladatokkal, inspirációs forrásnak jó, bár úgy látom, annak nem vagy híján :)

https://www.nand2tetris.org/

Amit virtualizálva csinálsz, ahhoz közeli dolog már létezik hardware-esen. A kis PIC-ek ilyenek. PIC10, PIC12 sorozat jellemzően.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Par otlet/gondolat korabbi tapasztalatok alapjan:

  • Kezdd a Harvard architekturaval: joval egyszerubb implementalni kesobb hardverbol azt ami Harvardos. Kulon progrmem es kulon i/o memoria: mindig rendelkezesre all az utasitas es mindig tudsz (szinkron v. aszinkron modon, amelyik epp' jobb) modositani a memoria tartalman.
  • Hasznald ezt az assemblert: https://github.com/hlorenzi/custom. Nagyon jo kis projekt, tudsz vele komplett kodokat (oke, binarist vagy hexat, tehat nem *.o vagy elf vagy ilyesmiket) generaltatni teljesen sajat architekturara. 
  • Kezdd a projekted implementalst ugy hogy egy sima visszaszamolo ciklus (label: mov rx, 100; dec rx; jnz label;), vagy ennek megfelelo jol lefusson. Ha ez jol megy akkor a call/ret-ig bezarolag minden egyszeru lesz.
  • Ha csinalsz stack-et (akar csak ugy pusp/pop szinten, akar call/ret modon) akkor az legyen szinten hardveres. 
  • Ha mar van call/ret-ed (akar memoria stack-es, akar hardver stack-es) akkor az interrupt-kezelest semmikepp ne hagyd ki! Az onnan mar nagyon elegansan szep lesz :)

Ez itten fentebb nagyjabol az avr1 architektura fobb jellemzoi is :) De persze csinald ugy ahogy epp' kedved van. En most olyasmi kis procit tervezgetek amivel egy CAN logikat lehet egyszeruen implementalni bitbang-jelleggel. Annak is kb hasonlo kovetlemenyei vannak mint amiket megfogalmaztal, bar mondjuk oda pont stack/call/ret nem kell - szoval vsz egyszeurbb is. 

Szerkesztve: 2020. 12. 09., sze – 10:53

Kiváló ötlet! Sok emberen segítene ha ezzel kezdődne az oktatás.

Mindenképp érdekes lenne, elolvasnám és ha jól sikerül ajánlanám. Viszont a megcélzott vcpu eléggé akadémikusnak tűnik, nehéz neki gyakorlati hasznosítást találni a tanuláson túl.
Hogy az assembly bonyolult lenne? Nekem konkréten ez tűnik a legegyszerűbbnek.
Nézzék meg mondjuk a windows api -t, vagy kezdőként a Tanenbaum féle Minix -et.
(Mondjuk engem leginkább a szimulátorok és az emulátorok érdekelnének, a kereskedelmileg kapható cpu -hoz. Bőven vnnak ilyenek de a használatuk eléggé nehézkes)

* Én egy indián vagyok. Minden indián hazudik.

Én örömmel várnom. Ha tetszik, megmutatom pár tanárnak akik programozást tanítanak, ennyi amit megtehetek. 

Én a magam részéről támogatom az ötletet, mert mindent támogatok ami Alkotásnak tűnik. Ez meg nagyonis annak tűnik. Bár ha belekotnyeleskedhetek így a távolból, a címtartománynak én is legalább egy 64K nagyságot javasolnék... De már ezt is csak rosszabb esetben, mert legyen az 4 GB ha megoldható (és miért is ne lehetne megoldani).

Értem én hogy tanulási célra meg stb, de 64K-ba már legalább valami egyszerűbb játékot össze lehetne szenvedni benne, ami kétségkívül megnövelné az izgalmasságát s így a tanulási élményét a nebulóknak.

De mondom, én most csak kívülről kibicelek, s kibicnek semmi se drága...

Nyugi, én meg a magam Peri nyelvében ítam már labirintusos (maze) játékot, igaz CLI képernyőre csak... s ezt amiatt említem mert nekem az is „egyszerűbb”. E fogalmat ugyanis úgy értettem ebben a kontextusban, hogy „nem igényel feltétlenül bonyolult grafikát”.

Manapság már a fiatalság mindent lecsepül ugyanis sajnos, ami nem csilivili. Ami nem villogó, nem életszerűen animált. az nekik mind „egyszerű”. Na így értettem.

Az a tetris azért ennek ellenére szép fegyvertény lehetett, alig több mint 1K-ban... Gondolkoztam annó én is hogy tetrist írok Periben, de letettem róla, főleg azért mert bevallom nem is igazán ismerem a szabályait. Életemben ha talán kétszer játszottam vele összesen, de nem nagyon tetszett. Hozzám közelebb állnak a labirintuos játékok, így egy olyat valósítottam meg.

Mondjuk azt bevallom, biztos nagyobb mint 1K...

4GB memória, védett mód és minden ... azaz bonyolult, nehezen megérthető.
Vagy a legegyszerűbb végrehajtó, akár csak 4 kB-nyi memória címzéssel, amiből a misztikum a legkönnyebben eloszlatható.

A verem bázisút sem véletlenül dobtam be az ötletelésben. Egyszerű, szép, játékos + dinamikusan bővíthető.
Bár a hétköznapi életben kevésbé ismert, a haditechnika és az űrkutatás háttereként egyszerűsége folytán szépen muzsikál.

Semmivel sem bonyolultabb 32 bit, mint 8 bit. Csak nagyobb. Akár lehet 32 bites szervezésű minden, és akkor nem kell még little/big endian kérdéskörrel sem törődni. Az más kérdés, hogy ha védett módot meg minden kutyafülét is akarunk, akkor az már bonyolult. De simán a 32 bites címzés nem az.

Ennek a válasznak köze nincs a little/big endiánhoz. A memória mérete független a tárolási sorrendtől, de a processzor bitszámától és címzési képességétől is.

Az endianness alapvetően arcitektúrális kérdés (volt), de ma már (a nagyobb processzorokon) inkább csak a hagyományoktól függ. A szoftvereseknek meg egy felesleges tulajdonság. ;) Egy modern processzor big endián, és akkor nincs szükség a használhatatlan ötletedre.

Nem a bonyolultság a kérdés, de ha elveket akarsz megértetni, akkor nem 8 számjegyű hexadecimális számokat kellene nézegetni, mert elviszi a fókuszt, feleslegesen terheli az ember agyát. Tanulni a 8 bitesek a legalkalmasabbak, miközben a gyakorlatban is jól alkalmazhatók.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A hexadecimális számok és bitek megtanulása csak gyakorlás kérdése. Inkább az a probléma, hogy az architektúra többeknek smafu. Így aztán értsd meg az alapelveket hardver ismeretek nélkül!

Megfordítva: Tanuld meg az alapokat egy egyszerű elvek szerint működő szerkezeten! Eddig jó. Aztán nem fog hasonlítani semmi valódira, és csak a korlátokkal fogsz találkozni.

Többször elhangzott, hogy nem cél egy már létező processzor elveinek a követése. Márpedig az egyes processzoroknak a felépítésükből is adódik néhány tulajdonságuk. Nézd csak meg ebben az egyes utasítások bemutatásához használt ábrákat! Pedig ez egy nagyon egyszerű/bonyolult proceszor. ;)

Nem arról beszéltem, hogy látod-e hexadecimális számjegyből annak kifejtett bináris alakját, mert azt feltételeztem. Ha tanulsz, akkor elég azt megjegyezni, hogy igen, akkor itt a 12-es memóriarekeszbe írunk 5-öt, amit amott eggyel megnövelünk, és 6 lesz. Ez érthető. Az viszont ellehetetleníti a tanulást, hogy a 0xd03e988c címre írunk 0x04bb99ff-et, amit amott eggyel növelve kapunk még mindig a 0xd03e988c címen 0x04bb9a00-t. Remélem, érted, mitől tanulható az első, és mitől nem a második.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Értem, de ez nem áll a 8 bites 256 bájtos gépre. (Egy bájtot meg lehet tanulni, mint a szorzótáblát.)

Pesze azt meg végképp nem értem, hogy miért nem lehetetleníti el a tanulást, ha a 3493763212 címre írunk 79403519-et. :-D

Az assembler meg érteni fogja a szimbólumokat tetszőleges radix mellett.

akkor nem 8 számjegyű hexadecimális számokat kellene nézegetni, mert elviszi a fókuszt, feleslegesen terheli az ember agyát.

Ez így van. Ebben abszolút egyetértek veled.
Volt szerencsém tesztelni ezt a kis gépet [a topik tárgya], hogy milyen hatást vált ki azokban, akiknek készült.
A tapasztalatok megleptek. A memória- és regisztertartalom megjelenítésénél a hexa ábrázolásmód ugye kikerülhetetlen. Na, hogy a dolog követhető, pontosabban, inkább követett legyen, kénytelen voltam már a példaprogramoknál [add, sub] olyan operandusokat választani, amelyek értéke kisebb mint tíz, hogy ne zavarjon be valami "hexadecimális" szám, mert az már akadályt képezett a megértésben és elfordulást váltott ki az érdeklődőkben. 

Ha nincs sok regisztered, ird ki hexaban es decimalisban is, vagy egymas melle, vagy gyorsan valthato modon! (pl. hotkey) Van, ami hexaban logikusabb, de van, amit decimalisban szoktunk meg (aritmetika). Plusz azzal, ha sok szamot lat egymas mellett mindket szamrendszerben, legalabb a hexat is szokja a tanulo (ha keves gepkozeli dolgot csinalt eddig, kelleni fog).

When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin

Köszönöm az ötletet.
Korábban, egy sokadik verzióban meg is valósítottam azt, amit írsz. Mondjuk akkor még más volt a koncepció, ott léptetni kellett a végrehajtást és egyszerre csak egy állapotot lehetett vizsgálni. Ott sajnos a hátrány az volt, hogy már 60-70 ciklus manuális léptetése is fárasztólag hat. Abban volt decimális, hexa és bináris megjelenítés is.  

Na de már bocsáss meg, ki az ördög beszélt „védett mód”-ról?! Én aztán biztos hogy nem!

Én egyszerűen nagyobb címtartományról beszéltem és kész ennyi.

Esetleg ha mindenáron valamiféle értelemben többszálúsítani akarjuk, még akkor se tennék bele „védett üzemmódot”. Ha én csinálnám meg, olyasmire vetemednék mint a C-64 megszakításrendszere. Tudom, az nem több szálú „igazából”, de egész jól „emulálja” vagy hogy is mondjam. Védett üzemmód ahhoz se kell.

Amúgy ilyesmit ami a topiknyitóban van, én már csináltam. És igen, épp 256 bájt címtartománnyal. De nem oktatási célra. Egy evolúciós algoritmust akartam kipróbálni, ahol a programok az „élőlények”... A „virtuális gépem” működött is szépen, azzal nem volt semmi baj. Maga az evolúciós algoritmus is működött technikai értelemben, de a célomat mégse értem el, mert rájöttem, ilyen feladatoknál nem az a kihívás hogy az algoritmust leprogramozzuk, hanem hogy az „élőplényeinknek” kitaláljunk egy kellően bonyolult virtuális vcilágot, olyan szabálykészlettel amik:

1. Megérthetőek viszonylag könnyen emberi ésszel (mármint, a „világ” felfogható a számunkra)

2. A szabályok mégis elég bonyolultak ahhoz, hogy érdekes irányokba befolyásolják az evolúciót

3. A szabályok mégse túl bonyolultak, mert ha azok lesznek akkor a szimuláció futása még erős gépen is lassú lesz.

Minthogy egy használható programnyelv megalkotása jobban érdekelt (ebből lett végül a Peri) így e projektet jegeltem. Talán még megvan valahol egy alkönyvtárban, de nem teszem közzé és nem kezdek róla blogsorozatot, egyrészt mert ugyanúgy csak trollkodás lenne belőle mint a Furor nyelvemnél volt, másrészt hagyom a terepet a topiknyitó kollégának. Különben is, nála mint írta az oktatási cél a lényeg, nálam meg sose az volt a cél, szóval ilyen értelemben még mondható is hogy az övé az elsőség.

Bár sok öröme nem lesz benne. Már megjelentek az első kötekedők ahogy olvasom. Késhegyre menő viták a HALT körül, mintha az lenne az egészben a legfontosabb...

De úgy kell neki. Tanulhatott volna az én esetemből: SEMMIT nem szabad közzétenni vagy megemlíteni a HUP-on amíg teljesen készen nincs!

Szerkesztve: 2020. 12. 12., szo – 16:10

Mi csináltunk hasonlót 4 éve.

Cortex M0-on futott a firware és azon volt implementált virtuális CPU. És abban futott a vezérlés.

32 bites fix méretű utasítások, saját memóriaterület (2K!), flash terület (SPI flash-ből kiajánlva).

Egy gond volt vele. Időkritikus műveleteknél néha picit belaggolt, mert a kód is (SPI) flash-ből futott, meg a CAN controller is (ugyan azon az) SPI-on volt. Így a motorvezérlő néha érdekes dolgokat csinált. :)

Volt millió 5let, pl az utasítások (SoC) RAM-ba cache-elése, lényegében L1 cache implementálása. Csak aztán nem ezt az utat választottuk.

Saját utasításkészlet, csak assemblyben lehet(ett) programozni és van compiler, ami a 'bytekódot' előállítja.

Azért én nem hagynám ki főleg az elején az irodalomkutatási részt. 

Borzasztóan elszomorodok, ha elvette a kedvedet ez a bikeshedding ami itt történt közben a komment szekcióban.

Szerintem nem vagyok egyedül azzal, ha azt mondom hogy jó ötlet és tövábbra is érdekel és várom (és nem pofázok bele a nulladik pillanatban mindenféle random vektorok mentén).