Instrukce logických operací
Logické instrukce jsou jednou z
dobrých pomůcek programátorů. ASM86 je schopen provádět
všechny běžné logické operace, a to se slovem nebo slabikou.
Chybí zde tedy instrukce pro jednotlivé bity. Ty však volbou
vhodných algoritmů můžeme lehce nahradit.
- NOT zdroj -
neguj všechny bity zdroje
- AND zdroj,
cíl - logický součin zdroje s cílem ulož do zdroje
(registr - hodnota, paměť - hodnota, registr - registr,
paměť - registr, registr - paměť)
- TEST zdroj,
cíl - logický součin zdroje s cílem, ale nastav jen
registr příznaků F (registr - hodnota, paměť -
hodnota, registr - registr, paměť - registr, registr -
paměť)
- OR zdroj,
cíl - logický součet zdroje s cílem ulož do zdroje
(registr - hodnota, paměť - hodnota, registr - registr,
paměť - registr, registr - paměť)
- XOR zdroj,
cíl - logický vylučovací součet zdroje s cílem
ulož do zdroje (registr - hodnota, paměť - hodnota,
registr - registr, paměť - registr, registr - paměť)
Kolikabitová operace je, určuje
opět specifikace zdroje a cíle. Instrukci TEST
použijeme k nastavení příznakového registru, a tak můžeme
větvit program, aniž bychom ovlivnili hodnoty zdroje a cíle.
Použití
logických operací
Vymaskování slabiky nebo slova
Často potřebuje programátor nastavit některé bity slabiky,
nebo slova do hodnoty log. 1, nebo 0. K tomu mu velmi dobře
poslouží právě logické operace AND nebo OR. Máme-li slabiku
ve tvaru XXXXAXXX v registru AL a chceme, aby bity X měly
hodnotu 0 a hodnota bitu A zůstala zachována, provedeme
instrukci AND AL, $08 (=00001000). Máme-li
slabiku ve tvaru XXXXAXXX v registru AL a chceme, aby bity X
měly hodnotu 1 a hodnota bitu A zůstala zachována, provedeme
instrukci OR AL, $F7 (=11110111).
Nulování registru
Zajímavější než instrukce MOV
registr,0 je nulovat pomocí XOR registr,
registr. Efekt je stejný, doba vykonání operace je kratší.
Zjištění zbytku po
celočíselném dělení mocninami 2
Kdybychom vždy, když chceme zjistit zbytek po dělení
mocninami 2 (a ten často potřebujeme) používali instrukci DIV,
program bychom zdržovali. Stačí si jen uvědomit, že můžeme
zjistit hodnotu bitů v řádech za log. 1 v binárním tvaru
dělence. Chceme-li zjistit zbytek po celočíselném dělení 2
(sudé, liché číslo) čísla v registru AL, stačí jen
použít instrukci AND AL,1. V registru AL je
potom jen buď 1 (liché číslo), nebo 0 (sudé číslo). Pro
lepší orientaci poslouží přehled:
- AND AL, 1
( 1 = 00000001) -> AL := AL mod 2 ( 2 = 00000010)
- AND AL, 3
( 3 = 00000011) -> AL := AL mod 4 ( 4 = 00000100)
- AND AL, 7
( 7 = 00000111) -> AL := AL mod 8 ( 8 = 00001000)
- AND AL, 15
(15 = 00001111) -> AL := AL mod 16(16 = 00010000)
Převod čísla v nezhuštěném
BCD na ASCII
Velmi jednoduchým prostředkem, jak převést číslo v rozsahu
0-9 do hodnoty jeho znaku v tabulce ASCII, je logický součet s
číslem $30 (to je stejné jako přičtení 48). Použitím
této úpravy čísel v kódu BCD je zobrazení i velkých
čísel jednoduché.
Příklad:
var slabika:byte;
znak:char;
begin
repeat
readln (slabika);
until slabika in [0..9];
asm
MOV AL, slabika {do registru AL předej hodnotu slabiky}
OR AL, $30 {převeď na ASCII}
MOV znak, AL {do proměnné znak předej ASCII hodnotu čísla}
end;
writeln (znak);
end.
V příkladu je načtené číslo
z intervalu 0..9 převedeno do ASCII s pomocí log. instrukce OR.
Před dalším příkladem si
musíme vysvětlit, jak ukládá Pascal řetězce (typu string).
Za řetězec je zde považováno pole slabik, které má na
prvním místě délku řetězce a na dalších místech jsou
kódy ASCII zapsaných znaků. Informace o délce řetězce je
důležitá pro jeho správné zobrazení. Ten proto nemusí
obsahovat speciální ukončovací znak.
Příklad:
var slovo:string;
i:byte;
begin
for i:=0 to 9 do
asm
MOV DI, OFFSET slovo {do registru DI ulož adresu proměnné slovo}
INC DI {posuň se až za slabiku délky řetězce}
XOR AH,AH {nuluj AH}
MOV AL,i {do AL vlož krok i}
ADD DI,AX {přičti krok k adrese (posuv po řetězci)}
OR AL,$30 {převeď obsah AL na ASCII znak}
MOV [DI],AL {přesuň znak do řetězce}
INC BYTE PTR [OFFSET slovo]{zvyš délku řetězce}
end;
writeln (slovo);
readln;
end.
Tento příklad vytvoří slovo
typu string s čísly od 0 do 9. To, že zatím nevíme, jak se v
ASM86 tvoří cykly, není na závadu. Prostě si pomůžeme
znalostmi z Pascalu.
Kódování
Každý rád chrání svá data před neoprávněným
přístupem kódováním. K tomu dobře slouží logická operace
XOR. Postup kódování naznačuje postup. Provedeme-li operaci
XOR s konstantou a kódovaným číslem, získáme kódované
číslo. Pokud s kódovaným číslem provedeme opět XOR se
stejnou konstantou, získáme zpět původní číslo. Čísla
kódovaná přidáme do EXE souboru programu. Před jejich
použitím je dekódujeme. Protože tato čísla mohou nést
např. jméno autora (v ASCII), je jméno pro běžného
uživatele po zakódování nečitelné (a tedy lehce
nepřepsatelné v souboru EXE). Pozor! Hodnota konstanty musí
být při kódování i dekódování stejná. Tento postup
můžeme libovolně pozměňovat podle úrovně našich znalostí
(např. xorovat první znak s druhým, druhý s třetím, . . .).
|