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

ÚÄÄÄ ÚÄÄÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄÚÄ ÚÄÚÄ ÚÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄÄÄÄÄÄÄÄ ÚÄÄ ÚÄ Ú ÚÄ Ja ljublju ASSEMBLY ÚÄÄ ÚÄÄ ÚÄ ÚÄ ÚÄ ÚÄ IX.rész ÚÄÄ ÚÄÄ ÚÄÄÄÄ ÚÄ ÚÄ Végül néhány logikai művelet.
AND utasítás (logical AND):
Használat: AND cél, forrás A cél és forrás bitjeire végrehajtja a LOGIKAI ÉS műveletet és az eredményt célba teszi. Az AND művelet végrehajtási táblázata:
cél | forrás | eredmény
0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1
CSAK akkor 1 az eredmény, ha MINDKIT bit 1 volt. Akkor hasznos, egy byte bizonyos bitjeit 0-ra akarjuk állítani, persze még sok hasznos dologra alkalmas az AND művelet de ez már a BOOLEAN algebra dolga és egyelőre nem hiszem, hogy szükséged lesz rájuk. Az AND utasítás (és a többi) lehetséges operandusait például az ASM.NG fileből lehet megtudni. Példa: Tegyük fel, hogy az 10011100b szám 2-ik és 3-ik bitjét nullázni akarom. Tudjuk, hogy az AND művelet eredménye akkor 0, ha legalább az egyik bit 0. Ezért ha a fenti számot 11110011b-vel AND-delem, akkor biztos, hogy az említett 2 bit nulla lesz, a többi pedig nem változik, hiszen ha egy bitet 1-gyel AND-delek, akkor nem változik meg az értéke, amint az a művelet táblából látszik.
NEG utasítás (NEGate):
Használat: NEG cél A célt kivonja nullából és ez lesz az eredmény, ez kerül vissza célbe. Ha cél 0, akkor CF=0 lesz, egyébként 1. Ha 80h-t vagy 8000h-t akarjuk negálni, akkor nem változik semmi csak az OF lesz 1. Ez a szám kettes komplemens számát képzi. Erről az előző cikkben írtam.
NOT utasítás (logical NOT):
Használat: NOT cél A cél minden bitjére elvégzi a LOGIKAI NEM műveletét. A NOT művelettáblája:
cél | eredmény
0 | 1
1 | 0
Ez a szám úgynevezett egyes komplemens számát képzi, amelyet hozzáadva az eredeti számhoz -1-et kapunk.
OR utasítás (logical OR):
Használat: OR cél, forrás A cél és a forrás minden bitjére elvégzi a LOGIKAI VAGY műveletet. Ennek műveleti táblája:
cél | forrás | eredmény
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 1
CSAK akkor 0 az eredmény, ha MINDKÉT bit 0 volt. Nagyon hasznos, ha egy byte néhány bitjét 1-re akarjuk állítani, de magát a byteot nem ismerjük. Példa: Akarjuk az 10100101b szám 1. és 6. bitjét egyre állítani. Ehhez a 01000010b számmal kell OR-olni, mert ha egy bitet egyel OR-olok, akkor az biztos egy lesz, míg ha 0-val, akkor nem változik. Ha nem világos nézd meg a művelettáblát.
XOR utasítás (eXclusive OR):
Használat: XOR cél, forrás A cél és a forrás bitjeire végrehajtja a KIZÁRÓ VAGY műveletet. Ennek művelettáblája:
cél | forrás | eredmény
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Az eredmény CSAK akkor 1, a két bit közül CSAK az egyik 1. Hasznos például ha egy regisztert nullázni kell, hiszen XOR AX,AX 0-t ad, mert minden bit megegyezik, de az egyező bitek 0-t adnak. Ezek a logikai műveletek nem csak a leírt pár dologra jók, de minden lehetséges felhasználásuk leírását nem érzem fontosnak, meg amúgy sincs türelmem őket összegyűjteni. Remélem még emlékszel a programra, ahonnan indultunk. Egy kicsit hosszú volt az utasításokról szóló rész, de ez kellett. Térjünk vissza a mi kis rövidített forrásunkhoz. Ezekhez a rövidítésekhez hasonló ötletekkel lehet rövidíteni a kódot, hogy ne legyen Microsoft style, vagyis ne legyen nagy. Ide már csak az utasításokat másolom be, a szövegek ugyan azok, mint az előző programnál. Ez egyébként a pelda2.asm egy része. program: mov ah,09h mov dx,offset question int 21h mov dx,offset menu int 21h mov dx,offset press_key int 21h input_character: mov ah,07h int 21h mov ah,09h cmp al,31h jb bad_key cmp al,33h jbe cool_guy not_cool_guy: cmp al,34h je fuck cmp al,35h je fuck cmp al,36h je learn bad_key: mov dx,offset do_not_play int 21h jmp input_character cool_guy: mov dx,offset good_guy int 21h jmp exit learn: mov dx,offset learn_it int 21h jmp exit fuck: mov dx,offset fuck_yourself int 21h exit: mov ah,4ch int 21h Amint látjátok az elejéről eltűnt két mov ah,09h. Ezt azért tehetem meg, mert a 21h/09h funkció az AH-t nem babrálja, ezért az megmarad 09h-nak. Ezzel 4 byteot spóroltunk. A karakter beolvasása után betettem egy mov ah,09h-et. Az AH ekkor semmi értékes infot nem tartalmaz így átírhatom, de később biztos lesz egy kiírás a képernyőre, amihez az AH-ban 09h kell. De ezzel az előre betöltéssel a következő négy kiírástól kitörölhetem a mov-okat. Ezzel 6 byteot takarítok meg. A szidás (fuck) kiírása mögül kitöröltem a jmp exit-et. Ez egyértelmű, mert úgyis 'rácsorog' a proggy a kilépésre. Ez 2 byteot jelent. Persze ezt a JMP-ot értelmes ember bele sem tenné. Végül a karakter kiértékelésénél egy kicsit bekavarok. Kivételesen ide írom mindkét verziót, hogy könnyebb legyen magyarázni. cmp al,31h cmp al,31h je cool_guy jb bad_key cmp al,32h cmp al,33h je cool_guy jbe cool_guy cmp al,33h je cool_guy Az első verzió szépen sorban megnézi egyezik-e AL 31h, 32h vagy 33h-val. A második ezzel szemben megnézi, hogy AL kisebb-e mint 31h. Ha igen, akkor biztos rossz a karakter. Ha AL nagyobb mint 31h, akkor még lehet jó. Ezért meg kell nézni vajon kisebb egyenlő-e mint 33h. Ha igen, akkor vagy 31h vagy 32h vagy 33h, amire ugyanaz a válasz. Úgy tűnhet ennek nem sok értelme van, hiszen csak 5 byteot jelent. De képzeld el hogy mondjuk az ABC betűire ugyanazt a dolgot kell csinálnod. Mennyivel szebb és persze rövidebb, ha megnézzük, hogy az érték benne van-e egy intervallumban, semmint szépen végig ellenőrizni minden lehetséges értéket. A sok ellenőrzést már leírni is sok. Lucifer of ZeroBit

©2000. Fearless Criminal Force. Minden jog fenntartva!