ÚÄÄÄ
ÚÄÄÄ ÚÄ
ÚÄ
ÚÄ ÚÄ
ÚÄ ÚÄ
ÚÄÚÄ ÚÄÚÄ
ÚÄ ÚÄ
ÚÄÄ ÚÄ
ÚÄÄ ÚÄ
ÚÄÄÄÄÄÄÄÄÄ
ÚÄÄ ÚÄ
Ú ÚÄ 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.
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:
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
|