Učebnice Assembleru 86

Tvorba podprogramů

Bloky programu, které vykonávají činnost často se opakující, nazveme podprogramem. Jejich použitím zjednodušíme program. Za podprogramy pokládáme procedury a funkce. Pascal umožňuje vkládat assembler i do obyčejných podprogramů. Můžeme také tvořit podprogramy pouze v assembleru. To vyjádříme zápisem assembler za definici procedury nebo funkce. Ty potom neobsahují klasické vymezení bloku begin...end, stačí jen assemblerovské asm..end (pokud tedy tvoříme podprogram jen v assembleru, uvedeme za definici označení assembler, blok vymezíme asm...end). S parametry pracujeme v podprogramech v souladu s tím, jak jsme je přes zásobník předávali. To znamená, že k parametrům volaným hodnotou přistupujeme jako ke klasickým proměnným, k parametrům volaným odkazem přistupujeme jako k ukazatelům (dosazujeme jejich adresu instrukcí LES, LDS).

Lokální proměnné

V okamžiku vstupu do podprogramu se na vrcholu zásobníku automaticky vytvoří místa pro lokální proměnné definované v části var podprogramu. V případě, že se jedná o pascalovskou funkci (není označena slovem assembler v definici), je navíc vložena speciální proměnná @RESULT určená k předání funkční hodnoty (ta je i stejného datového typu). Před návratem z funkce je obsah proměnné @RESULT automaticky předán do registrů předepsaných pro návrat hodnoty (pokud tedy tvoříme funkci s vloženým assemblerovským blokem, předáme funkční hodnotu do proměnné @RESULT, ve funkci s označením assembler vracíme funkční hodnotu v registrech, ve kterých funkční hodnotu očekává volající (AL, AX,..), jak bylo uvedeno v části o volání podprogramů). Lokální proměnné používáme stejně jako globální (s tím rozdílem, že jejich segmentová adresa není v DS).

Význam registru BP

Registr BP je v době vykonávání podprogramu nasměrován na vrcholek zásobníku v okamžiku vstupu do něj. Proto použitím nepřímé bázové adresace s pomocí tohoto registru můžeme přistupovat k:

  • parametrům - příčítáním k hodnotě v BP (např. [BP + 6] je označení pro přístup k parametru)
  • lokálním proměnným - odečítáním od hodnoty v BP (např. [BP - 2] je označení přístupu k prvnímu parametru typu word)

Vzhledem k tomu, že se o tyto přepočty adres může postarat překladač, je jednodušší používat pro přístupy k proměnným a parametrům jen jejich symboly uvedené v definici podprogramu nebo části var.

Příklad:

uses crt;
procedure pocitej (a,b:word;var c,d:word);assembler;
asm
 MOV AX,a       {do registru ax, vlož hodnotu a}
 ADD AX,b       {přičti b}
 LES DI,c       {do ES:DI vlož adresu c (to je výstup součtu)}
 MOV ES:[DI],AX {na adresu ES:DI zapiš součet}
 MOV AX,a       {to samé pro rozdíl}
 SUB AX,b
 LES DI,d
 MOV ES:[DI],AX {a na adresu d zapiš rozdíl}
end;

function bez1 (a:word):word;assembler;
asm
 MOV AX,a       {do AX vlož hodnotu parametru a}
 DEC AX         {kdyby to nebyla čistě assemblerovská funkce, tak}
                {přidám řádek:}
                {MOV @RESULT, AX fce hodnotu pak také vrátí v AX}
end;

var a_,b_,c_,d_:word; {hlavní program}
begin
 a_:=40;b_:=5;
 clrscr;
 pocitej (a_,b_,c_,d_);
 writeln (a_,'+(-)',b_,'=',c_,'(',d_,')');
 c:=bez1 (a_);
 writeln (a_,'-1=',c_);
 readkey;
end.

Směr