________ÚÄÄÄ ÚÄÄÄ
ÚÄ ÚÄ
ÚÄ ÚÄ
ÚÄ ÚÄ
ÚÄÚÄ ÚÄÚÄ
ÚÄ ÚÄ
ÚÄÄ ÚÄ
ÚÄÄ ÚÄ
ÚÄÄÄÄÄÄÄÄÄ
ÚÄÄ ÚÄ
Ú ÚÄ 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
|