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 DIZ 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 SIFunkce je obdobná jako u STOSB.
Instrukce provede následující akci :
MOV BYTE PTR ES:[DI],DS:[SI] INC DI INC SITento 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ž.