Virtuális gép, Assembler, távirati stílusban [III. rész, az assembler]

 Miért is csinálom én ezt az egészet?
Amikor számítástechnikai tárgyú tanulmányaimat végeztem, egy napon fordulópont következett be az életemben. Ez a fordulópont az a pillanat volt,

amikor először sikerült megértenem a processzorok működési mechanizmusát. Tehát, magát a folyamatot, ami bennük végbemegy és, hogy ami részegység bennük van, az mi célt szolgál. Ettől a pillanattól kezdve éreztem azt, hogy képes vagyok uralni egy számítógépet*, hogy képessé váltam átlátni azoknak a perifériáknak a működését is, amelyeket előtte még csak nem is láttam. Attól a pillanattól kezdve a korábbinál jobban megértettem a programok működését, azok szerveződését, szerkezetét is. Olyasféle élmény volt ez számomra, mint amikor a hónapokig tartó homályban bolyongás után az ember egyszer csak kiérkezik a fényre és az őt körülvevő dolgokról nem csak zavaros sejtése lesz, hanem azok mindegyike határozott kontúrokat kap, felismerhetővé válik.

* Ez nem jelent egyet a jó programozással, inkább azzal egyenértékű, hogy az ember mindent képes megvalósítani a géppel, amit csak akar, már ha annak egyéb objektív akadályai nincsenek.  Vagy olyan, mint amikor az ember megtanul sakkozni és képessé válik érdemben játszani. Nem feltétlenül lesz belőle egy Kaszparov, de képzelhető, mekkora előnye lesz azokhoz képest, akik még a játék szabályait sem ismerik teljes egészében.

    Úgy gondolom, hogy azok akik kedvtelésből foglalkoznak számítástechnikával, az ilyen, vagy hasonló élménynek megélését akadályozza az, hogy talán nem is tudják pontosan, hogy milyen ismeretekre lenne szükségük.
    Fél éve tett nyilatkozatomban azt állítottam, hogy a processzorok távolról sem olyan bonyolult és kiismerhetetlen szerkezetek, mint amilyennek a legtöbb ember képzeli azokat. Ez igaz is. Viszont az is kétségtelen, hogy egy szimplább processzor alapos megismeréséhez még a jobb képességű emberkéknek is elég mély levegőt kell venniük.
Úgy gondolom, nem azért, mert megtanulhatatlan, nem is azért, mert olyan haj de bonyolult lenne, hanem inkább azért, mert több olyan dolgot kell hozzá ismerni, amit másutt nemigen használ az ember és ennek okán nincs is róla semmiféle előismerete. A szükséges tudás tehát nem sok, hanem inkább speciális ismeretek csoportja.
    Ha az ember, hozzám hasonlóan azt tűzi ki céljául, hogy az érdeklődőknek megpróbálja megadni azt az élményt, amit egykor maga is átélt, akkor nehéz dolga lesz. Leginkább azért, mert az emberek nem annyira tanulni, hanem inkább tudni vágynak. Ezért a tudásért cserébe alkalmasint hajlandóak tanulni is, de ez csak akkor kecsegtet sikerrel, ha a szükséges képességek megléte mellett a megtanulandó is kellően érdekes, izgalmas a befogadó számára. Hát, mit tagadjuk, egy processzor esetében, annak beltartalmát elemezve kevesek hevülnek piros izzásig.
    Akkor mi lehet a megoldás? Mondjuk a lényegi részek torkon való ledugdosása, egyesével. Ám ez a módszer csak egyetemeken hasznosítható, ráadásul, ott is csak szolid hatásfokkal.

Más lehetőség van?

    Hacsak az nem, hogy az ember épít egy olyan processzort, ami a használatban lévők abszolút minimuma. Ami csak azokat az összetevőket tartalmazza, ami az elemi  működéshez, annak bemutatásához, szemléltetéséhez kell. Én is így tettem.
Ha felsorolnám, hogy egy ilyen szimpla processzor megismerése mennyi minden elsajátítását igényli, nem lenne túl rövid a lista. A regiszterek, azok funkciója, a memória (!), a címezhetőség, a szegmensek és azok szerepe,  a stack* és annak helye, működése, a kilenc (valójában tíz) utasítás, azok funkciói, a funkciók kihatása. Mindezt meg is érteni, a viszonylatokat, kapcsolódási pontokat felismerni, ráadásul egy nekifutásra. Hát, ez azért nem kevés.

* Nem véletlenül nem tértem ki a stack-re, annak működésére bővebben, és nem véletlenül lett egy szint mélységű sem.

Persze azok, akik már a tudás birtokában vannak, talán nem tartanák a listát hosszúnak, hiszen ők már kapun belül vannak, de hát, nem is nekik készül ez a sorozat.

    Nem csodálnám, ha az érdeklődők jó része, akár a sajátos stílus, akár a tálalás, akár a terjedelem, miegyéb okán első olvasatra nem lennének képesek 100 %-ban magukévá tenni az olvasottakat. Nekik azt ajánlom, hogy amivel nincsenek tisztában, vagy ami megválaszolásra váró kérdéseket generál bennük, arra bátran világítsanak rá egy-egy hozzászólásban, mert egészen biztos vagyok abban, hogy értő segítséget fognak kapni azoktól, akik ennek a szakmának a művelői, mesterei.
    Az is egy járható út, ha többszöri nekifutásra, olvasatra próbálja valaki megemészteni az anyagot és a számára kérdéses pontoknak másutt is utána olvas.  

    Biztos akadnak, akik csalódtak, mert ennél többet vártak.
    Nekik azt tudom mondani, hogy mindenki kedvére nem lehet tenni, egy-egy ilyesféle anyag nem szólhat egyszerre a kezdők, a mediorok és a vérprofik számára. A tartalom már megszabja a fogyasztók körét. Az talán a csalódottak közül kárpótolni tud néhányat, hogy a forrás olvastával kapnak egy know-how-t. Egy vázlatot, ami elég sekélyes ahhoz, hogy a megértést, befogadást segítse, ugyanakkor elég informatív ahhoz, hogy a saját igény megvalósításában támogatást, sillabuszt biztosítson.
    Az assembler is és a VM is elég transzparens, könnyen befogadható, más nyelvekre játszva portolható. A bővíthetősége is - úgy gondolom - vitán felül áll. Már csak tudom, elvégre én gallyaztam le.           

Végezetül:

    Ez az írás a szakmában a processzorok építésénél alkalmazott általános konvencióktól - legyen az működésbeli, vagy mnemonik (ez az utasítások neve) terén kialakult, megcsontosodott hallgatólagos egyezmény, informális szabály - csak nüansznyi mértékben tér el, tehát az itt, ebben a néhány részben megszerezhető tudás, ismeret, minimum 90 %-ban hibamentesen transzportálható, hasznosítható, valid.

A jövőre vonatkozóan: Ezen a részen kívül még két bejegyzést tervezek.
A következő a VM processzorával foglalkozik majd, persze annak forrását is publikálni fogom.
A befejező rész a programozhatóságról, a bővithetőségről fog szólni.

========================================================================

Az Assembler

    A VM utasításai mind megvannak, hiánytalanul. Az assemblerről ugyanez már nem mondható el. Egy hiányzik. Az előző részben titokká minősített, pirossal kihúzott utasításról lesz szó. Ez az utasítás teszi lehetővé, hogy változókat használhassunk a VM-ben. Az utasítás neve egyébként DAT.

    A beharangozóban említettem, hogy az eredetileg tervezettnél mindenből sokkal kevesebb lesz. Ezt az igéretemet következetesen be is tartom. A 300+ soros assembert csonkoltam, kevesebb mint 140 sorra redukálódott. A VM-et is sikerült megritkítani. A 300+ sorból nem sok maradt.

    De mit is kell tudnia egy assemblernek? Fel kell tudnia dolgozni a forrásfájlt. Ez első körben annyit tesz, hogy a forrásban szereplő karakterekről kideríti, hogy azok mifélék. Na de, mifélék lehetnek?

    Lehetnek ugye számok (0..9), lehetnek betűk (A..Z) és lehetnek bármi egyebek.

    Hogy az assemblerünk minél egyszerűbb lehessen, annak előfeltétele, hogy az assembly nyelvünk se legyen túl bonyolult. Nem is lesz az.
A nyelv kulcsszavai (mnemonikok) kivétel nélkül három karakterből fognak állni. A mennyiségük sem túl számos, mindössze kilencen vannak, bár tény, az assembler program szerkezete olyan, hogy a jelenleginél sokkal több - akár 2-300 - kulcsszó feldolgozása, túl sok plusz befektetést nem igényelne. Maga az assembler szerkezetileg semmivel nem lenne összetettebb. Ez is volt a szándék, a könnyű bővíthetőség.

    A nyelv grammatikája, szabályrendszere is nagyon egyszerű. A RET-en kívül minden más kulcsszót egy paraméterrel kell kiegészíteni. Ez a paraméter az eddig ismertetett (!!!) utasítások esetében kivétel nélkül egy-egy memóriacím, ami 0-tól  255-ig (vagy amíg a memória tart) bármelyik integer lehet.
    Ennek a paraméternek a decimális ábrázolása szintén három karaktert igényel, maximum. Hexadecimálisan csak kettőt, de oda kell egy prefixum, vagy postfixum (előtag vagy utótag) is, amiről az assember tudni fogja, hogy éppen nem egy decimális, hanem hex számmal van dolga. Ezért a hexadecimális számok is maximum három karakterhelyet igényelnek.

    Minden sort a pontosvessző karakter zár le. Ennek az a szerepe, hogy a sorlezáró karakter után kommentet lehessen elhelyezni a programban.
    Az assembler feldolgozója sor-orientált. A sorlezáró karakter utáni részt már figyelembe sem veszi.
Ebből mindjárt az is kitűnik, hogy a forráskód egy-egy sorában csak egy utasítás állhat.  

    Egy  sor formátuma úgy néz ki, hogy a sor elején van az utasítás kulcsszava és azt követi legalább egy space-szel, TAB-bal elválasztva az utasítás paramétere.
A RET utasítás az egyetlen, amely nem igényel paramétert. (Az már ott van a Stack-ben a MEM[00]-n)

A változók

    Látható, hogy az assembler is és a VM is egyszerű, ám ennek az egyszerűségnek ára van. Nézzük, mivel fizetünk:  
    Változók használatára a programokban úgy van lehetőség, hogy a DAT nevű kulcsszó mögé írjuk magát a változót, pontosabban a DAT mögé kerül egy tetszőleges egy byte-os érték.  Az ezekre az értékekre való hivatkozás pedig a lokalizációjuk (elfoglalt helyük) alapján történik, tehát például a

DAT  06;
DAT  02;
DAT  09;
DAT 10h;

a memóriában (annak is első sorában) így fog kinézni:[00] [06] [02] [09] [10]
A sorban a nulladik hely (ez most 00 tartalmú) a stack számára van fenntartva. A többi a feldolgozott, elhelyezett (A)DAT, egymás után, "érkezési sorrendben".  

    Ha mondjuk 9-et akarnék kivonni az ACCU tartalmából, akkor a SUB 03; utasítás sorra lenne szükségem (SUB 3; is megfelel).    

    Ezeket az értékeket az assembler az első (tehát nem a nulladik!) memóriahelytől kezdődően helyezi el.  Ezért van 1 értékkel inicializálva az IP nevű változó.

    Fontos, hogy DAT csak és kizárólag a program elején, minden más utasítás előtt lehet és a számuk nem haladhatja meg a teljes memória egy negyedét+(minusz kettő (ez a stack és kimeneti port)).

    Az efféle formalizálás lehetővé tenné, hogy az assembler szinte csak sorok beolvasásából és azok alkalmas helyen való megvágásából álljon.
Az első vágást közvetlenül a sorvégjelünk (pontosvessző) előtt lehetne megejteni (alábbi képen piros). Ezzel leválasztanánk a kommentet, a második vágást pedig az utasítás és ha van, annak paramétere között (alábbi képen kék). Ezután már csak trimmelni kellene az utasítás és a paraméter két végéről az esetleges space karaktereket.  

katana

    Mi azonban (a továbbfejleszthetőség okán is) inkább egy másik, rögösebb utat, a karakterenkénti feldolgozást fogjuk választani. Ez a mód szépen, szekvenciálisan, karakterről karakterre végig lépdel a forrásfájl teljes tartalmán és megfelelően kiértékeli azt.

    A számunkra "hasznos" karaktereknek két csoportja van. Az angol ABC betűi (Aa..Zz), ezek alkotnak egy halmazt és a numerikus karakterek (0..9) fogják alkotni a másik halmazt.

    Ehhez szükséges két függvény, amely eldönti a beérkező karakterről, hogy az micsoda. A forráskód karakterei sorban egymás után kerülnek beolvasásra, egy Ch nevű, karakter tipusú változóba (pufferbe).  

    A teljes assembler mindössze tíz függvényből/procedúrából áll.
A főbb függvények: 

Alphabet    - függvény, bemenő paramétere a Ch, visszatérési értéke boolean. Ha Ch tartalma egy betű akkor true, ha nem akkor false.     
Numeric     - függvény, bemenő paramétere a Ch, visszatérési értéke boolean. Ha Ch tartalma "szám" akkor true, ha nem akkor false.
DropWhite - procedúra, amelynek feladata, hogy amíg a Ch tartalma SPACE vagy TAB karakter addig tovább olvassa a forrást (GetCh procedúra ismételt meghívása).  Feladata a soreleji, sorközi "üres" (whitespace) karakterek kiszűrése.     

Token   - string tipusú, maximum három karakter hosszú változó. A beolvasott szám vagy kulcsszó puffere.

GetToken  - String tipusú függvény. Ennek visszatérési értékét kapja meg a Token, aminek milyenségét dolgozza fel az assember főprogramja.

    A program működése:

    A beolvasott forráskód minden karakteréről eldönti, hogy az betű-e, szám-e vagy valami más.  Mivel az utasítás csak betű, a paraméter meg csak szám lehet, ennek eldöntése nem túl bonyolult feladat. Ha nem is betű nem is szám, akkor ejti a karaktert.
Ha a karakter milyenségét sikeresen felderítette, akkor közvetlenül az aktuális karakter után érkező karakterek hozzáfűzésével meglesz az utasítás, vagy a paraméter. Az utasításokat ezután jószerivel csak meg kell feleltetni az OP-kódjaikkal és a memória következő szabad rekeszébe írni. Ugyanez történik a paraméterekkel, csak a tipusuk előtte konvertálódik karakterből tényleges számmá (char-ból integerré). Hogy éppen hova íródnak az opkódok vagy számok, azt az IP nevű változó növelésével menedzseljük (pontosabban, az assembler menedzseli, mert ez teljesen automatikusan történik).        

    Most tényleg távirati stílusba kapcsolok és sorra pozicionált telegramokban próbálom átadni az assembler működési mechanizmusát.

[013] A változók közül az IP (aminek tipusa byte) az '1' értéket kapja.
[111] A főprogram a Ch puffer feltöltésével indul. Ez a GetCh meghívásáva ltörténik.
[114] Ezután a GetToken függvény próbál meg kinyerni egy Tokent a forráskódból.
[071] A GetToken először a DropWhite [037] segítségével leszűri az esetleges SPACE és TAB karaktereket,
[072] majd továbblép és a Ch tartalmát vizsgáltatja először az Alphabet, és ha az false, akkor a Numeric függvénnyel.
[077] Ha ez utóbbi is false, akkor amit a Ch tartalmaz, azzal tér vissza a hívóhoz és adja át a tartalmát a Token nevű string tip. változónak.

itt visszatérünk a főprogramba:

[115] Ha a Token épp' egy sorlezáró karakter akkor a sor végéig csak ejti a beolvasott karaktereket, hiszen azok az "értéktelen" kommentek.
[117] Ha a Token nem CR (carriage return), nem  LF (linefeed)  és nem sorlezáró, akkor
[119] a Token első karakterének vizsgálata következik, hogy kiderüljön, az utasítás-e (alfabetikus) vagy paraméter (numerikus).
[121] Ha utasítás, akkor azt deríti ki, hogy DAT utasítás-e vagy valami más.
[122] Ha az utasítás nem DAT, akkor egy boolean tip. változót (ez a NonDAT) bebillent (true) és az IP-t az INITIP értékére állítja (hiszen ha nem DAT akkor már vége az adatszegmens feltöltésének, átlép a kódszegmensre)
[094] Ha az utasítás DAT, akkor annak vizsgálata jön, hogy az aktuális DAT belefér-e még az adatszegmensbe? Ha igen, akkor ott kap elhelyezést és az adat számláló  inkrementálódik eggyel, ha nem, akkor error,
[095] Ha a Token alfabetikus, attól még előfordulhat, hogy nem része az utasításkészletnek. Ennek vizsgálata, mivel a program nyúlfarknyi, a MemLoad függvényben történik. Ha a Token nem ismert (CASE of), akkor Error.

[126] Ha a Token első karaktere szám, akkor a Token egy tipuskonverzió (stringből integer) után a memóriába kerül. Hogy hova, azt az IP jelöli ki. Ezután az IP értéke növekszik eggyel.
[131] Ha a Token valami rendkívüli, akkor még a MemLoad függvény meghívása előtt Error-ra fut a program.

[133] Fenti műveletsor történik ismételten, a forráskód legutolsó karakteréig.
[135] Ha a program nem lép ki hibával, akkor az utolsó lépés a MemSaveToFile függvény meghívásával a felépített memóriatartalom fájlba írása.  

A kimeneti fájl (memória-kép file) már a mi VM-ünk által fogyasztható, futtatható bináris.   

A program meghívása (Windows környezetben):

uasm.exe <forrasfile.prg  kimenet.bin  vagy  uasm.exe <adder.prg  adder.bin   

===================================================================

Bővíthetőség (ötletek):

Az én bővített verziómban van - egyebek mellett -
tizenhat utasítás, mint pl.
- ACCU increment/decrement (így könnyebb és memória-takarékosabb a számlálós ciklusok szervezése)
- SWP, ami megcseréli az accu és egy tetszőleges memóriahely tartalmát,
- "rafinált" bitmanipulációs utasítások, stb.
Az assembler fogadni képes hexadecimális ($F8) és bináris (.10011011) formátumot is (Itt jegyzem meg, aki e téren bővíteni szeretne, az prefixumban gondolkozzon, mert úgy könnyebb dolga lesz).
Szabadon választott címről indulhat a program végrehajtás (van org utasítás)
A binárisok nem csak egyszerű memória képfile-ok, hanem van saját formátumuk.
A verem két szint mélységű, vannak flag-ek is, van bemeneti port, a memória pedig 384 byte. Ez utóbbi trükkös, mert az IP regiszter továbbra is csak 8 bites. :)
 
Emellett perifériák is illeszthetőek a VM-hez és három féle üzemmódban dolgozhat.
1. Interaktív, lépésenkénti programvégrehajtás lehetősége, +backstep.
2. log mode. Ez a betöltött programot lefuttatja és minden változást log-ba ír.
3. Mint az előbbi de a log nem plain text hanem html formátumú, így a perifériákat és azok állapotát is képes (grafikusan) megjeleníteni.

De sok más is megvalósítható, nagyobb utasításkészlet, sokkal több memória, megszakítás rendszer, stb.

 

 

 

          

microASSEMBLER

Hozzászólások

Szerkesztve: 2021. 06. 27., v – 10:44

Továbbra is tetszik a hobbiprojekted.

Egyébként ezt láttad? Az alkotója 4 utasításra redukálta a világát.

NOR + 6 bit MEM
ADD + 6 bit MEM
STA  + 6 bit MEM
JCC  + 6 bit cím

+11 memóriacím spéci értékekkel van feltöltve. A pdf-ben leírja, hogyan valósítja meg makrókkal a CLR, LDA, NOT, JMP, JCS, SUB műveleteket.

Köszönöm a tetszésnyilvánítást!

 

MCPU

Igen, ezt a CPLD-be faragott kis remekművet már volt szerencsém megcsodálni. Te hívtad fel a figyelmet rá egy blogbejegyzésedben, ha jól emlékszem, Sok helyre (LED villogtatáshoz, bit billegtetéshez) ez is elég volna, Külön érdeme a zseniális egyszerűség mellet, hogy hardveresen is megvalósítható. A tetejébe, olcsón.  

Legyél te is hülye, muja állat, támogasd a tolvaj dakotákat.

Hardveresen szinte mind megvalósítható, kérdés hogy mekkora hardverben. Lehetőségek a logikai kapcsolatok felépítésére:

  1. Elemi diszkrét alkatrészek (ellenállás, dióda, tranzisztor)
  2. TTL IC
  3. CPLD ... kb 300 .. 400 makrocelláig
  4. FPGA

Nyilván a leg látványosabb, egyúttal a leg macerásabb a diszkrét alkatrészekből való felépítés. Erre csak egyszerűek jöhetnek szóba. A CPLD és FPGA implementációk IC-n belül valósítják meg a procit. Ott csak a VHDL/Verilog kód van a kezedben meg annyi mérőjel, amennyit kivezetsz lábakra.

CPU implementációk: https://opencores.org/projects?expanded=Processor

Rosszul fogalmaztam.  :)

Én a megvalósíthatóságot arra értettem, hogy ha mondjuk valaki az enyémet akarná HW-ben megcsinálni, akkor lenne még dolga elég, az mCPU alkotója viszont ezt a lépést már megtette, az érdeklődők számára még a tartalom is elérhető.  

Egyébként, szivesen építenék összetettebb TTL vagy akár DTL logikát.
Lehet, hogy idén, valamikor késő ősszel neki is fogok. 
Az általad ismertetett egy bites cpu-val meg az a tervem, hogy leemulálom, és csinálok hozzá egy környezetet, amelyben több, akár négy ilyen egy bites CPU-t lehetne programozni, plusz köréjük építeni egyszerűbb logikákat, kivánság, igény szerint. Magát a procit meg is valósítottam.   

Legyél te is hülye, muja állat, támogasd a tolvaj dakotákat.

Like meg minden. A szokasos, tervezoi dontesek miatti kotozkodest most en is megteszem: me pont pacal? Oke, talan olvashatobb, mint egy gzipelt Perl kod, vagy egy Brainfuck, de azert nem sokkal. Ja, es miert pont beagyazott kepkent?

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

me pont pacal?

Hát, ez egy nehéz kérdés. Ezzel akár már zenei izlésről  is beszélgethetnénk. :) A pascallal nekem nincs bajom, rugalmas, könnyen tanulható nyelv. Azt nem tudom, miért tartod nehezen olvashatónak? Nekem erről éppen ellenkező a véleményem.
A téma iránt érdeklődők nyilván nem c++ expertek. Nem tudom, mit használnak, mit ismernek. Ez jó választásnak tűnt.

es miert pont beagyazott kepkent?

Elsősorban azért, mert fontos volt a sorszám, hogy utalhassak rá vagy az esetleges érdeklődő rá tudjon mutatni a számára valamiért kérdéses sorra.  Azt is lényegesnek tartottam, hogy szines legyen a forrás és jól tagolt. 
Maga a kód, ha levonom az üres sorokat és azokat, amelyek tartalma nem több mint egy begin vagy egy end, akkor talán nincs száz sor.
Úgy gondoltam, aki jól gépel, az hamar beírja, aki meg nem, az, legalább gyakorol egy kicsit. De ha igény van rá,  feteszem valahova. Az fontos, hogy itt is meglegyen, a szöveggel, a sorszámozott utalásokkal együtt.

Legyél te is hülye, muja állat, támogasd a tolvaj dakotákat.

Talán meg lehetne gondolni, hogy a konstans adatok ne az adatterületre, hanem a kódterületre kerüljenek (mivel az utóbbi a nagyobb). Ilyen konstans adatok például az ugrási címek: mivel minden ugrás indirekt, minden ugrási célcímhez kell egy-egy byte, ami jelen esetben az adatterületet fogyasztja.

Köszönöm a javaslatodat. Tisztelettel, de megvallom, nem látom túl sok értelmét.
Ezt a gépet profik nem nagyon fogják programozni.
A kezdők pedig nem hiszem, hogy memóriabeli korlátokba ütköznének. Ha ennek veszélye fennáll, akkor már jó eséllyel  találnak rá megoldást is. Azt is figyelembe kell venni, hogy az adatszegmens csak most tűnik szűkösnek. A 256 Byte-os kiépítésnél már hatvankettő az ami most még csak tizennégy.
 
Egyébként, van lehetőség rá, hogy a majdani használó egy pillanat alatt átdefiniálja a szegmensek méretét, de akár arra is, hogy a kódszegmensben adatokat helyezzen el. Erre több mód kínálkozik. A kódszervezés is segíthet. A kimeneti port, ha nincs azonnal használva, átmenetileg tárolhat adatot (változó értékét), de a meglévő 14-ből is képezhető újabb és ki is írható a kódszegmens nem használt részére. Ezek az adatok ugyanúgy elérhetőek azon a területen és műveletek is végezhetők velük.
Sőt, lehet már a program írásánál is adatterületként használni a kódszegmenst. Elég ha a programunk végén kiadunk plusz  utasításokat majd azok paraméteréül a kivánt adatokat. Így azok bekerülnek a kódszegmensbe, de nem hajtódnak végre, mert azt megakadályozzuk egy eléjük helyezett "JMP bármelyik nullára"  ugrással, viszont az LDA, ADD, SUB, CMP utasítások felhasználhatják őket.

Lehet formátumot is gyártani a futtatandó programnak, és akkor minden egyes bit kihasználható.
Ennek a legegyszerűbb módja az, hogy a legelső byte értéke lesz a kódszegmens kezdő-címe. Ennek értékét kell a betöltés után az IP regiszternek átadni és kész.   
 

Legyél te is hülye, muja állat, támogasd a tolvaj dakotákat.