Lucifer of ZeroBit - Ja ljublju ASSEMBLY VI. rész

________ÚÄÄÄ ÚÄÄÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄÚÄ ÚÄÚÄ ÚÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄÄÄÄÄÄÄÄ ÚÄÄ ÚÄ Ú ÚÄ Ja ljublju ASSEMBLY ÚÄÄ ÚÄÄ ÚÄ ÚÄ ÚÄ ÚÄ VI.rész ÚÄÄ ÚÄÄ ÚÄÄÄÄ ÚÄ ÚÄ Helló mindenki! Újra itt vagyok, hogy fossam a szót. Azt ígértem a múltkor, hogy ebben a számban a DOS filekezelését próbálom közelebb vinni hozzátok. Ezt be is tartom, de elõször bemutatnék egy példaprogramot. A program elõtt még van egy kis mondandóm. Nem tudom feltünt-e valakinek, hogy ASSEMBLY tanfolyamnak vagyon nevezve ez a töménytelen szöveg és én mégis mindenféle DOS funkciókkal nyaggatlak benneteket. Ezért mielõtt még hülyének gondolnátok adok a cikksorozatnak egy elfogadhatóan precíz címet: Az MS-DOS és kompatibilis operációs rendszerekkel felszerelt IBM PC kompatibilis számítógépek programozása, lehetõségeinek elérése ASSEMBLY nyelv használatával, melynek során néhány feladatot, így a file-kezelést és még egy-két dolgot átengedünk az operációs rendszernek vagy a BIOS-nak. Tehát nem csak az ASSEMBLY szépségeibe óhajtalak titeket bevezetni, hanem a DOS mocskos, bûzös, bogarakkal (gyk.: bug) teletûzdelt poklába is. Most már tényleg elkezdhetjük. Bocsánat, a PTS-DOS-ra az elõbbi szép szavak nem vonatkoznak, bár néhol nem is teljesen kompatibilis az MS-DOSsal :-) Bizonyára emlékeztek, hogy az elõzõ számban mindenkit arra buzdítottam, írjon valami kis egyszerû menüválasztós proggyt. Nos nem tudom, hányan tettétek ezt meg, de azért remélem sokan. A program maga elég egyszerû, de példának megteszi. A forrását ide is bemásolom, de külön cikkben is megvannak a példák. A pelda4.asm-ban van egy hiány: a jnc ok5 után kell egy pop cx is. Az okát majd egy késõbbi cikkben elmondom. Ha a példák kódja nem a legjobb, az a sietségnek tudható be. A program a pelda1.asm nevet viseli. Van egy második változata (pelda2.asm) is. Ez az elsõ rövidített változata. Akkor a forráskód (ez a hosszabb verzió): title pelda1 comment* Példaprogram az ASSEMBLY OKTATÓ cikksorozathoz Egy egyszerû menüt ír ki és választást kér. A választás alapján egy kis szöveget ír ki. Kommentek a kódban, a használt utasítások rövid ismertetése a cikkben. * segment code para public 'code' assume cs:code,ds:code,ss:code,es:code org 100h start: jmp program question db 'Szerinted milyen az ASSEMBLY nyelv?',13,10,13,10,'$' menu db '1. Qrva jó csak még nem ismerem eléggé!',13,10 db '2. Nagyon jó csak kicsit sokat kell írni hozzá!',13,10 db '3. Nekem tetszik...',13,10 db '4. Eléggé szar!',13,10 db '5. SHIT!!!',13,10 db '6. Nem értek hozzá',13,10,13,10,'$' press_key db ' Nyomd meg a válaszod számát!',13,10,'$' do_not_play db ' Ne szórakozz!! Jó?',13,10,'$' good_guy db ' Látom jó ember vagy, lassan halj meg!',13,10,13,10,'$' fuck_yourself db ' Tudod mit? Dögölj meg!!',13,10,13,10,'$' learn_it db ' Itt az alkalom, hogy megtanuld!!',13,10,13,10,'$' program: ;--------------------------- mov ah,09h ; A jól ismert 21h/09h mov dx,offset question ; függvénnyel kiírjuk a int 21h ; kérdést. mov ah,09h ; Ugyanezzel a funkcióval mov dx,offset menu ; írjuk ki a lehetséges int 21h ; válaszokat is. mov ah,09h ; Itt kérjük a megfelelõ mov dx,offset press_key ; billentyû lenyomását int 21h ; szintén 21h/09h-val input_character: ;A 21h/07h funkcióval lehet mov ah,07h ; egy billentyûre várni int 21h ; (a cikkben leírom) cmp al,31h ; Ha AL 31h, 32h vagy 33h je cool_guy ; akkor tetszik a válasz cmp al,32h ; és ezen érzésünknek je cool_guy ; hangot is adunk egy kis cmp al,33h ; szöveggel je cool_guy ; cmp al,34h ; Ha AL 34h vagy 35h je fuck ; akkor nagyon nem nyerõ cmp al,35h ; a válasz, ezért jól je fuck ; megsértjük a válaszolót cmp al,36h ; Ha AL 36h, akkor egy kis je learn ; önreklám következik mov ah,09h ; Ha nem jó a lenyomott mov dx,offset do_not_play ; billentyû, akkor int 21h ; figyelmeztetés jön és jmp input_character ; új billentyûre várunk cool_guy: ; mov ah,09h ; Itt jön egy kis dícséret mov dx,offset good_guy ; int 21h ; majd egy gyors kilépés jmp exit ; learn: ; mov ah,09h ; Ez az önreklám mov dx,offset learn_it ; int 21h ; és szintén kilépünk jmp exit ; fuck: ; mov ah,09h ; Ez a szidás mov dx,offset fuck_yourself ; int 21h ; na és persze a kilépés jmp exit ; exit: ; mov ah,4ch ; Itt a vége fuss el véle int 21h ;--------------------------- code ends end start Azt hiszem elég jól kommentezett, ezért csak az új dolgokra térek ki. A 07h DOS függvény (Direct Console Character Input without Echo): A standard beviteli eszközrõl vár egy byteot és azt az AL-ben adja vissza. Ha a billentyûzet ez az eszköz (és általában az), akkor a karakter ASCII kódját adja. A standard eszközökrõl még ebben a számban beszélek, ugyanis a filekezeléshez tartoznak. Ez a függvény nem vizsgálja a Ctrl-Break vagy Ctrl-C billentyûket. A 08h DOS függvény (Console Character Input without Echo): Ugyanaz, mint a 07h, csak ez figyeli a Ctrl-Break és Ctrl-C-t is. Ezek után nekiesek és leírom egy csomó assembly utasítás használatát, elvégre mégiscsak az assmblyrõl szólna a cikkem. Igyekszem mindenhol érthetõ lenni. A rövidített forrást majd az utasítások után veszem elõ. CMP utasítás (CoMPare): Használat: CMP cél, forrás Végrehajtja a cél-forrás mûveletet, de nem tárolja a végeredményt, csak az eredménynek megfelelõen állítja be a FLAG regiszter bitjeit. Nevébõl is látszik, hogy csak álmos õ, de nem be... Ja bocs! szóval, hogy összehasonlításra használják. A cél és a forrás lehetséges értékeit most nem sorolom fel, ugyanis a Norton Guide asm.ng filejában nagyon jól benne van. Általában feltételes ugróutasítások elõtt használják. Feltételes ugróutasítások: Vannak néhányan. Gyakorlatilag a FLAG regiszter összes értelmes bit kombinációjára van egy ilyen ugrás. A következõ felsorolásban elõször az ugrás feltételét jelentõ bitkombinációt írom le, ezután pedig azt, hogy ilyen kombináció általában mikor fordul elõ. Az ugrás igazi feltétele minden esetben a leírt bitkombináció. Akkor kezdõdjön a felsorolás:
JA | Jump if Above, Akkor ugrik ha CF és ZF is 0, magyarul ha egy SUB vagy CMP utasításnál a cél operandus nagyobb volt mint a forrás. Akkor használható, ha a célt és forrást elõjel nélkülinek tekintjük. Hogy ez pontosan mit jelent és mi a jelentõsége, azt az utasítások után próbálom elmondani.
JAE | Jump if Above or Equal, Akkor ugrik, ha CF=0, vagyis ha egy SUB vagy CMP utasításban a cél nagyobb vagy egyenlõ volt a forrásnál. Ennél is elõjel nélkülinek tekintjük a számokat
JB | Jump if Below, CF=1 esetén ugrik, egy SUB vagy CMP utasításnál a cél kisebb volt mint a forrás. Itt is elõjel nélkülinek kell tekinteni a számokat
JBE | Jump if Below or Equal, CF=1 vagy ZF=1-nél ugrik, azaz ha egy SUB vagy CMP utasításnál a cél kisebb vagy egyenlõ volt a forrásnál. Ki gondolná, de ez is elõjeltelen számokra vonatkozik
JC | Jump if Carry, ugyanaz mint JB, az azonosságokról is beszélek még
JCXZ | Jump if CX register Zero, akkor ugrik, ha CX=0
JE | Jump if Equal, ha ZF=1 ugrik, egy SUB vagy CMP utasítás során a cél egyenlõ volt a forrással
JG | Jump If Greater, akkor ugrik, ha ZF=0 és SF=OF, azaz ha egy SUB vagy CMP során a cél nagyobb, mint a forrás. Ne keverd össze a JB-vel, mert ennél ELÕJELES számokat feltételezünk
JGE | Jump if Greater or Equal, ha SF=OF, akkor ugrás, vagyis ha egy SUB vagy CMP során a cél nagyobb vagy egyenlõ forrásnál. Itt is elõjeles számokat vizsgálunk
JL | Jump if Less, SF<>OF kell az ugráshoz, szóval ha egy CMP vagy SUB során a cél kisebb mint a forrás, elõjelesen tekintve
JLE | Jump if Less or Equal, ha SF<>OF vagy ZF=1, azaz ha egy CMP vagy SUB végrehajtásánál a cél kisebb vagy egyenlõ a forrásnál, persze elõjelesen
JNA | Jump if Not Above, ugyanaz, mint a JBE
JNAE | Jump if Not Above or Equal, JB szinonimája
JNB | Jump if Not Below, JAE-vel azonos
JNBE | Jump if Not Below or Equal, Ugyanaz mint JA
JNC | Jump if Not Carry, ha CF=0, akkor ugrik
JNE | Jump if Not Equal, ZF=0 esetén ugrás, azaz ha egy CMP vagy SUB során cél nem egyezik a forrással
JNG | Jump if Not Greater, ugyanaz, mint JLE
JNGE | Jump if Not Greater or Equal, mint JL
JNL | Jump if Not Less, azonos JGE-vel
JNLE | Jump if Not Less or Equal, JG-vel azonos
JNO | Jump if No Overflow, ugrik, ha OF=0
JNP | Jump if No Parity, ugrik, ha PF=0
JNS | Jump if No Sign, ha SF=0
JNZ | Jump if Not Zero, ugyanaz, mint JNE
JO | Jump If Overflow, ugrás, ha OF=1
JP | Jump if Parity, ha PF=1, akkor elugrik
JPE | Jump if Parity Even, JP-vel egyezik
JPO | Jump if Parity Even, JNP-vel azonos
JS | Jump if Sign, ugrik, ha SF=1
JZ | Jump if Zero, vagyis JE
Gondolom feltûnt mindenkinek, hogy jó néhány utasításnak 2, de van amelyiknek 3 betûszava is van. Ezek a szavak ugyanazt az utasítást jelentik a programban, a debuggerek nem is tudják õket megkülönböztetni, mert nem is lehet. Ezek a változatok csak a forrás könnyebben olvashatóságát segítik. Például ha egy CMP után a ZF-re vagyok kíváncsi (az eredmény nulla volt-e vagy sem), akkor a JE vagy JNE formát használom. De ha egy rutin a ZF-en ad át jelzést, akkor a JZ és JNZ párt használom, mert itt szó nincs egyenlõségrõl vagy egyenlõtlenségrõl, de a két ugróutasítás ugyanaz lesz. Általában lehet ezeket a változatokat úgy használni, hogy ha kiolvasom õket, akkor a gondolatmenetemet tükrözzék. Például nem akkor gondolok ugrásra, mikor nagyobb vagy egyenlõ (JG), hanem mikor nem kisebb egy szám (JNL) a másiknál. Ez most kukacoskodásnak tûnhet de majd programozás során meglátod, hogy nem is olyan nagy baromság. A következõ cikkben elmagyarázom mi is az az elõjel nélküli vagy elõjeles számokra vonatkozó feltételes ugrás. Ezen kívül összeadunk, kivonunk, szorzunk, osztunk, logikai mûveleteket végzünk és byteokat forgatunk. Lucifer of ZeroBit

©2000. Fearless Criminal Force. Minden jog fenntartva!