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!