Tohle bude pravděpodobně poslední lekce věnovaná instrukcím. Naplácám sem včechny důležitější instrukce, o kterých jsem ještě nepsal. Postupem času by sem také mohly(na čtenářské žádosti - čte to vůbec někdo ??) být přidány ještě nějaké další. Tak hrrr na to, ať už se konečně můžem vrhnout na rezidenty, viry a další vylomeniny.
Toto je jedna z prefixových instrukcí. Instrukce napsaná jako parametr(není to úplně přesné označení, viz. dále) se opakuje tolikrát, kolik je registr CX. Překladač tuto instrukci přeloží jako DB 0F2H a pokračuje v kompilaci následující instrukce. Procesor jakmile najde tento prefix, zapamatuje si, že další instrukci má provádět CX-krát a začne jí provádět. To se hodí např. pro práci s řetězci(přesun dat, hledání, porovnávání).
Příklad uvedu až u dalších instrukcí ...
Podobné jako REP, ale přestane opakovat, pokud CX=0(jako u REP) a nebo pokud se ZF <> 0.
Instrukce provede následující akci :
MOV ES:[DI],AL
INC DI
Z toho je vidět možnost využití této instrukce ve spojení s
REP. Třeba chci vynulovat 10000 bytů v paměti :
MOV CX,10000
XOR AL,AL
REP STOSB
Instrukce provede následující akci :
MOV AL,DS:[SI]
INC SI
Funkce je obdobná jako u STOSB.
Instrukce provede následující akci :
MOV BYTE PTR ES:[DI],DS:[SI]
INC DI
INC SI
Tento MOV je pouze demonstrační, tuto konstrukci nelze použít.
Tahle instrukce je již mnohem důležitější než ty předchozí,
protože pouhým MOV nelze přesunout
data z paměti do paměti. MOVSB navíc po přesunutí bytu ještě přičte
oba offsety, takže se o ně nemusíš starat a lze ji proto použít
po prefixu REP. Příklad programu : Mám dva řetězce S1,S2 v Pascalovském
formátu(S1[0] = velikost, zbytek data) a chci provést toto přiřazení :
S2 := S1;
MOV SI,OFFSET S1
MOV DI,OFFSET S2
PUSH DS
POP ES ; Neboli MOV ES,DS
XOR CH,CH
MOV CL,BYTE PTR DS:[SI-1]
INC CX ; Dám do CX délku řetězce S1
REP MOVSB ; Přesun
MOV SI,OFFSET S1
MOV DI,OFFSET S2
PUSH DS
POP ES ; Neboli MOV ES,DS
XOR CH,CH
MOV CL,BYTE PTR DS:[SI-1]
INC CX ; Dám do CX délku řetězce S1
MOV DX,CX ; Zálohuji si jí do DX
SHR CX,2 ; Vydělím CX čtyřmi(budu kopírovat po čtyřech bytech)
REP MOVSD ; Přesun
MOV CX,DX
AND CX,3 ; Dodělám zbytek po dělení čtyřmi
REP MOVSB
Neboli - nejdříve zkopíruji řetězec po DWORDech a zbylé byty dozkopíruji jednotlivě. Pokud je délka např. 14 bytů, pak celý řetězec i s nultým indexem(velikost) zabírá 15 bytů. 15 SHR 2 je 3. Zkopíruji tedy nejdříve 3x4 byty. Pak vezmu oněch 15 bytů a zjistím zbytek po dělení čtyřmi(AND CX,3) = 3. Pak zkopíruji zbylé tři byty a je to.
Ještě jedna poznámka k řetězcům. Směr posunu offsetu(INC DI, INC SI) u řetězcových instrukcí závisí na nastavení vlajky
Nyní instrukce pro jednoduché nastavování některých FLAGů. Jsou dva druhy : CLx(clear, vynuluj vlajku x) a STx(set, nastav vlajku x).
Flagy jde samozřejmě měnit i jinak, ale trochu složitěji(třeba chci nastavit CF) :
PUSHF ; Uložím flagy do zásobníku
POP AX ; Načtu si je do AX
OR AX,1 ; Nastavím první bit(CF)
PUSH AX
POPF
Načte z portu číslo <adresa> hodnotu a uloží ji do <kam>. Ovšem <kam> musí být vždy AL, pro 16-bit hodnotu AX, případně EAX. Pokud je <adresa> < 256, pak lze napsat přímo číslo, jinak musíš jako <adresa> použít registr DX.
Zapíše na port číslo <adresa> hodnotu <co>. Podmínky pro parametry jsou stejné jako u IN.
Následuje nijak nesetříděný seznam posledních instrukcí :
Jak tak píšu seznam "posledních důležitých, zbylých instrukcí," tak stále zjišťuji, na co všechno jsem zapomněl. Instrukce LOOP se používá v cyklech. Provede následující činnost :
DEC CX
JNZ <návěští>
Neboli - dokud se CX nerovná nule, skoč na <návěští>.
| Úvodní stránka | Posuny a rotace | Rezidentní programy |
Stránku připravuje Lukáš Valenta,
1. v celostátním kole soutěže v programování, kategorie mládež.