Příkazy

Operátory slouží k provedení nějaké operace s danou hodnotou. Příkazy naproti tomu donutí počítač něco dělat.

Prázdný příkaz

Tento příkaz je velmi jednoduchý : ; (ano skutečně jen jeden středník)

Tento příkaz nic nedělá. Lze ho napsat všude tam, kde by mohl být jiný příkaz. Nejčastěji se používá při ladění (for I:=1 to 10 do ; begin, zde tento příkaz vyřadí for z provozu). Dále pak v některých situacích zvyšuje přehlednost a přenositelnost programu (za posledním příkazem před endem se středník nepíše, když ho tam však napíšeme, jedná se o prázdný příkaz a nic se nestane. Je to výhodné - později budeme moct za tento příkaz psát, aniž bychom ten středník dodělávali.)

Přiřazovací příkaz

Tento příkaz je také jednoduchý Proměnná := Výraz;

Nejprve se vyhodnotí výraz a jeho hodnota se přiřadí dané proměnné. Její původní hodnota se ztratí. Je tedy možné např. přiřazení A:=A+1.7;

Volání procedury

NazevProcedury;
Také se jedná o velice jednoduchý příkaz. Můžeme využít předem definované procedury, či si definovat své vlastní.

Příkaz skoku

goto Návěští;
Příkaz skoku. Po provedení toho příkazu přeskočí program na dané místo (vynechá některé příkazy, či se někam vrátí). Všechna návěští musíme definovat v sekci label, v kódu je pak vyznačíme takto Název:
Raději na konkrétním příkladě :

program Skace;
label SkocSem;
begin
SkocSem:
write('Haha');
goto SkocSem;
end.

Názvy návěští smí být maximálně čtyřmístná kladná čísla, či libovolné identifikátory. Není povolen skok dovnitř do bloku nebo ven z bloku (Do a z podprogramu, procedury, funkce,..). Může se skákat do složeného a ze složeného příkazu (což ovšem značně znepřehlední program). Skoku se sice lze vždy vyhnout, za zvlášť nepříznivých okolností je ale jeho použití nejjednodušší a nejpřehlednější formou řešení (a pouze v takovýchto případech se vyplatí)

Efektivní využití goto je možné pouze v podmíněném příkazu a příkazu vícenásobného větvení. (Zamyslete se nad tím, proč je jinde tento příkaz zbytečný).

Příkaz inline

Inline(Cislo[/Cislo]...);
Nejprve krátce k syntaxi : Parametr Inline tvoří čísla (nejčastěji v hexadecimální podobě - tedy s $ před sebou), která jsou oddělena lomítkem (v případě jednoho čísla lomítko nepíšeme).
Tento příkaz umožňuje vložit do našeho programu instrukce procesoru (vloží dané slabiky přímo do kódu našeho programu). Nesprávné použití zkolabuje počítač (Windows tedy skoro jakékoliv použití zakazují).
Chceme-li z daného čísla využít jen jednu (první) slabiku (=byte), použijeme unární operátor < (Ten dané číslo zkrátí na jednu jedinou slabiku). Chceme-li naopak z jednoho bytu vytvořit slabiky dvě, použijeme operátor > (Jako druhou slabiku generuje 00);
Tedy např.
Inline($FA);
- Tato instrukce zakáže hardwarové přerušení.
Inline(<$13A7/>$3A); Vloží do výsledného kódu byty $A7 (skutečně, vzhledem k uložení v paměti je A7 první slabikou čísla 13A7 :), $3A $00 (> doplní nulami);

Pomocí Inline lze využít i instrukce procesoru, které standardní Pascal nezná (Např. instrukce MMX). Podívejte se do Sysmana, na tabulku instrukcí (která slabika odpovídá které instrukci assembleru.)

Strukturované příkazy

Tzv. strukturované příkazy se vyznačují tím, že v jejich definici se objevuje více rezervovaných slov, která jsou od sebe nějakým způsobem oddělena.

Složený příkaz begin - end

begin
 Příkaz1;
 Příkaz2;
 ...
 PrikazPosledni
end;

Nejjednodušší strukturovaný příkaz. Slouží především tam, kde je z důvodu syntaxe nutné použít příkaz jediný a my jich tam potřebujeme vměstnat více (např. u cyklů či podmíněných příkazů). Za posledním příkazem před endem není středník (my ho tam ale psát budeme, středník se vyhodnotí jako prázdný příkaz a pokud budeme chtít později něco připsat, nebudeme muset na ten středník myslet.)

Složený příkaz asm - end

asm
 Instrukce1
 Instrukce2
 ...
 InstrukcePosledni
end;

Tento příkaz umožňuje vložit instrukci assembleru do našeho kódu. Překladač umí zpracovávat instrukce I2086 a některé další (všechny novější procesory tyto instrukce podporují). Všimněte si, že za instrukcemi není uveden středník (i když pochopitelně tam prázdný příkaz napsat můžeme).

Podívejme se nyní na to, co překladač pascalský překladač assembleru zvládá. Rozlišuje tyto registry (AX, BX, CX, DX, AL, AH, BL, BH, CL, CH, DL, DH; dále CS, DS, ES, SS, IP, SI, DI, SP, BP a pochopitelně všechny vlajky).

Při psaní instrukcí pamatujte na to, že maximálně jedna hodnota smí být z paměti (u mov), zbytek musí být registry !!!
Seznam nejdůležitějších instrukcí (podívejte se do Sysmana) :

Aritmetické instrukce

Aritmetické instrukce
Pořadí Instrukce Význam
1 ADD dest, src Sečte dest + src a výsledek uloží v dest
2 INC dest Zvýší dest o jedna
3 SUB dest, srt Odečte dest - src a výsledek uloží v dest
4 DEC dest Sníží dest o jedna
5 CMP dest, src Porovná dest a src (nedestruktivně odečte a nastaví vlajky)
6 NEG dest Změní znaménko Dest
7 MUL src Násobí, je-li src 8-bitové, násobí AL*src a výsledek uloží do AX, je-li src 16-bitové násobí AX*src16 a výsledek uloží do AX:DX
8 DIV src Opak násobení, zbytek po celočíselném dělení uložen v AH (je-li src 8bitový), či v DX (je-li src 16-bitový)
9 AND dest, src Bitově znásobí dest a src a výsledek uloží do dest
10 TEST dest, src Bitově znásobí dest a src (nedestruktivně) a podle výsledku nastaví vlajky
11 OR dest, src Bitově logicky sečte dest a src a výsledek uloží do dest
12 XOR dest, src Bitově exkluzivně sečte dest a src a výsledek uloží do dest
13 NOT dest Bitově zneguje Dest (přehodí bity na opačné)

Instrukce posunu a rotací

Instrukce posunu a rotací
Pořadí Instrukce Význam
1 SHL dest, count Bitový logický posun doleva, Count je 1, nebo CL (s 1 je instrukce mnohem rychlejší)
2 SHR dest, count Bitový logický posun doprava, Count je 1, nebo CL (s 1 je instrukce mnohem rychlejší)

Instrukce přenosu dat

Instrukce přenosu dat
Pořadí Instrukce Význam
1 MOV dest, src Přemístí hodnotu src do Dest (ale ne z paměti do paměti - aspoň jeden údaj je registr nebo číslo)
2 XCHG dest, src Prohodí hodnoty src a dest
3 IN AL(AX),port8(16) Načte do AL (AX) data z portu port8 (16)
4 OUT port8(16),AL(AX) Pošle do port8(16) data z AL (AX)
5 PUSH src Uloží src nahoru do zásobníku
6 POP dest Načte ze zásobníku horní hodnotu a přemístí ji do dest (registru)
7 PUSHA Uloží všechny důležité registry nahoru do zásobníku (Funguje pouze, jsou-li zapnuté instrukce 286)
8 POPA Načte ze zásobníku důležité registry (Funguje pouze, jsou-li zapnuté instrukce 286)

Instrukce řízení programu

Instrukce řízení programu
Pořadí Instrukce Význam
1 JMP kam Skočí na kam
2 JCXZ kam Je-li CX=0 skočí na kam
3 LOOP kam Odečte od CX 1 a je-li CX<>0 skočí na kam
4 JB/JC kam Skočí, je-li menší (po provedení CMP,..)
5 JE/JZ kam Skočí, je-li rovno (po CMP,..)
6 JG/JNGE kam Skočí, je-li větší (po CMP,..)
7 JNE/JNZ kam Skočí, není-li rovno
8 INT n Zavolá přerušení n (takový malý podprográmek, který např. obsluhuje klávesnici, myš,..)

Instrukce řízení procesoru

Instrukce řízení procesoru
Pořadí Instrukce Význam
1 CLI zakáže maskovatelné hardwarové přerušení
2 STI povolí maskovatelné hardwarové přerušení

Podmíněný příkaz

if Podminka then Prikaz;
if Podminka then Prikaz1 else Prikaz2;

Chceme-li, aby se nějaký příkaz vykonal pouze v případě, že je splněna jistá podmínka, použijeme tento, tzv. podmíněný příkaz. Prikaz (Prikaz1) se vykoná, jestliže daná podmínka má hodnotu true. Prikaz2 (Větev else) se naopak vykoná pouze v případě, že daná podmínka má hodnotu false.

Podmínka = libovolný výraz, jehož výsledným typem je Boolean
Prikaz - jeden jediný příkaz, chceme-li aby se vykonala sada příkazů, musíme použít příkaz složený (či definovat vlastní proceduru)

Příkaz vícenásobného větvení

case OrdinarniPromena of
    Hodnota1:Prikaz1;
    Hodnota2:Prikaz2;
    ...
end;
case OrdinarniPromena of
    Hodnota1:Prikaz1;
    Hodnota2:Prikaz2;
    ...
    else PrikazJinak;
end;


Potřebujeme-li vykonat nějaký příkaz podle toho, jakou hodnotu má jistá ordinální proměnná, použijeme tento příkaz. V případě, že daná ordinální proměnná nabývá Hodnoty1, provede se Prikaz1 (zase jen jeden příkaz - nejčastěji tedy příkaz složený), v případě, že nabývá Hodnoty2, provede se Prikaz2. V případě, že nenabývá žádných z uvedených hodnot, provede se větev else (PrikazJinak). Větev else pochopitelně nemusí být uvedena (stejně tak jako u podmíněného příkazu if...then...)

Case se používá, je-li daných hodnot více než dvě (pro jednu či dvě možné hodnoty je výhodnější použít if...then a if...then...else...)
Pochopitelně je možné použít více hodnot naráz :

case A of
 1..6 : Writeln('A je mensi nebo rovno sesti');
 1,3,5,7,9 : Writeln('A je licha cislice');
 8 : Writeln('A je suda cislice vetsi nez sest');
 else Writeln('A neni cislice);
end;

Vždy se vykoná jeden jediný příkaz, je-li tedy např. A=1, pak se napíše pouze, že jde o číslo menší rovno šesti, to že se jedná o číslo liché se nenapíše.

Pro úplnost poznamenejme, že dané ordinální proměnné se říká selektor a že maximální rozsah selektoru je 65536 hodnot.
Příkaz vícenásobného větvení bývá občas také nazýván přepínačem.

Příkazy cyklů

Chceme-li, aby se určitý úsek kódu opakoval, použijeme cykly. V Pascalu rozlišujeme tři typy cyklů. Nejuniverzálnějším cyklem je cyklus while. Těla cyklů mohou obsahovat standardní procedury Break a Continue.

Break - okamžitě ukončí cyklus a skočí za něj
Continue - skočí k podmínce a znovu ji vyhodnotí (prostě vynechá všechny příkazy, až do konce cyklu)

Pomocí těchto příkazů se lze vyhnout většině skoků.Nemusím snad připomínat, že (podobně jako u goto) je jejich efektivní použití možné pouze za if či case.

Příkaz cyklu while

while Podminka do Prikaz;

Pokud je Podminka=true, prováděj příkaz.
Jako obvykle je Podminka libovolný výraz s výsledným booleovským typem. V průběhu Prikazu (těla cyklu) pak musíme zajistit, aby se hodnota Podminky měnila, jinak se program "zacyklí" - bude cyklus opakovat neustále dokola (nevyskočíme-li z něho někde pomocí Break).
V případě, že je podmínka=false, cyklus se neprovede ani jednou.

Současné událostní programování lze pomocí tohoto cyklu přenést i do Pascalu. Prostě celý program uzavřeme do while, neustále testujeme co se děje, stane-li se něco důležitého, zavoláme příslušnou proceduru (která třeba donutí ukončit program, tím, že změní podmínku cyklu...)

Pomocí while je také možné naprogramovat všechny ostatní cykly.

Příkaz cyklu repeat

repeat
 Prikaz1;
 Prikaz2;
 ...
 PrikazPosledni
until Podminka;

Příkazy v těle cyklu repeat se provedou a není-li na konci cyklu splněna podmínka, opakuje se celý cyklus repeat od začátku. Oproti while má tu výhodu, že příkazy se provedou alespoň jednou.

Všimněte si dále, že za posledním příkazem před until zase nemusí být středník. (Ale my ho tam psát budeme).

Cyklus repeat se nejčastěji používá ke kontrole uživatelem zadaných dat, nejsou-li údaje v pořádku, ať uživatel zadává, dokud se mu to konečně nepovede...

Příkaz cyklu for

for OrdinalniPromenna := Zacatek to Konec do Prikaz;
for OrdinalniPromenna := Zacatek downto Konec do Prikaz;

Nejjednodušší cyklus. Daná ordinální proměnná při něm nabývá hodnot Zacatek do Konec. (Zaciname-li s Zacatkem vyšším než Konec, je nutné napsat downto, jinak se cyklus neprovede).
V těle cyklu zásadně neměníme hodnotu dané OrdinalniPromenne - mohlo by to vést ke kolapsu programu či jeho zacyklení.
Z pochopitelných důvodů je Prikaz nejčastěji příkazem složeným.

Vyzkoušejte si to raději na konkrétním příkladu :

for Znak:='a' to 'z' do Write(Znak);
for Cislice=9 downto 0 do begin
            Writeln(Cislice);
            Writeln('Zbytek po deleni sedmi je : ', Cislice mod 7);
              end;

Chceme-li proměnnou měnit při každém průchodu cyklu třeba o 2 a ne o 1, máme dvě možnosti : pomocí if ... then Continue přeskočit nežádoucí cykly (což je pěkná blbost, ale jde to) nebo si zadefinovat jinou proměnnou a na začátku každého cyklu ji změnit o požadovanou hodnotu.

Příkaz with

with Nazev do Prikaz;
with Nazev1, Nazev2,... do Prikaz;
Tento příkaz slouží k usnadnění práce. V průběhu příkazu nemusíme neustále dokola vypisovat Nazev., Nazev1. či Nazev2. ,... překladač sám zajistí, aby se tyto názvy doplňovaly. V případě, že takto jsou takto zpřístupněné dvě proměnné stejného názvu, záleží na kompilátoru, kterou z nich zvolí (nejčastěji to bude posledně uvedený název).

Efektivní použití with je očividně možné pouze s využitím složeného příkazu (kvůli jednomu příkazu se nám with nevyplatí).

Příklad:

var Pracovnik:record
        Jmeno:string;
        Vek:Byte;
        Plat:Longint;
          end;
    Dite:record
        Jmeno:string;
        Vek:Shortint;
     end;
begin
 Pracovnik.Jmeno:='Leos';
 with Pracovnik do
  begin
   Jmeno:='Igor';
   Vek:=34;
   Plat:=9863;
  end;
 with Pracovnik, Dite do
  begin
   Jmeno:='Alena';
   Vek:=15;
   Plat:=10000;
  end;
Writeln('Dite : ', Dite.Jmeno, '/', Dite.Vek); {I zde by bylo pouziti with vyhodnejsi}
Writeln('Pracovnik : ', Pracovnik.Jmeno, '(',Pracovnik.Vek,') / ', Pracovnik.Plat);
end.

To je pro dnešek vše. Nic si z toho nedělejte, pokud vám nejsou jasné příkazy inline a asm (a zbytek je v pohodě). Bylo to přece jen takové lehké opakování.