Bloky programu, ktoré vykonávajú činnosť často sa opakujúcu, nazveme podprogramom. Ich
použitím zjednodušíme program. Za podprogramy považujeme procedúry a funkcie.
C++ umožňuje vkladať assembler i do obyčajných podprogramov. Môžeme tiež
tvoriť podprogramy iba v assembleri. S parametrami pracujeme v podprogramoch
v súlade s tým, ako sme ich caz zásobník odovzdávali. To znamená, že k
parametrom volaným hodnotou pristupujeme ako ku klasickým premenným, k
parametrom volaným odkazom pristupujeme ako k ukazovateľom (dosadzujeme
ich adresu inštrukciou LES, LDS).
Lokálne premenné
V okamihu vstupu do podprogramu sa na vrchole zásobníka automaticky vytvoria miesta pre
lokálne premenné definované v podprograme. V prípade, že sa jedná o pascalovskú
funkciu, pred návratom z funkcie je potrebné operátorom return odovzdať
návratovú hodnotu funkcie. (Pokiaľ teda tvoríme funkciu s vloženým assemblerovským
blokom, odovzdáme funkčnú hodnotu do pomocou operátora return, vo čisto
assemblerovskej funkcii vraciame funkčnú hodnotu v registroch, v ktorých
funkčnú hodnotu očakáva volajúca (AL, AX,..), ako bolo uvedené v časti
o volaní podprogramov). Lokálne premenné používame rovnako ako globálne
(s tým rozdielom, že ich segmentová adresa nie je v DS).
Význam registra BP
Register BP je v dobe vykonávania podprogramu nasmerovaný na vrchol zásobníka v okamihu
vstupu do neho. Preto použitím nepriameho bázového adresovania s pomocou
tohoto registra môžeme pristupovať k:
- parametrom - pričítaním k hodnote v BP (napr. [BP + 6] je označení pre prístup k parametru)
- lokálnym premenným - odčítaním od hodnoty v BP (napr. [BP - 2] je označenie prístupu k prvému
parametru typu word)
Vzhľadom k tomu,
že sa o tieto prepočty adries môže postarať prekladač, je jednoduchšie
používať pre prístupy k premenným a parametrom len ich symboly uvedené
v definícii podprogramu alebo premenných podprogramu.
#include <stdio.h>
#include <conio.h>
typedef unsigned int word;
void pocitaj(word a, word b, word &c, word &d) {
asm {
MOV AX,a // do registra ax, vlož hodnotu a
ADD AX,b // pričítaj b
MOV di, c
MOV [di],AX // na adresu c zapíš súčet
MOV AX,a // to isté pre rozdiel
SUB AX,b
MOV DI, d
MOV [DI],AX // a na adresu d zapíš rozdiel
}
}
word bez(word a) {
// word res;
asm {
MOV AX,a // do AX vlož hodnotu parametra a
DEC AX // keby to ale bola čisto assemblerovská funkcia, tak
// pridáme ešte zakomentované riadky
// MOV res, AX // funkcia hodnotu potom tiež vráti v AX
}
// return res;
}
word wa, wb, wc, wd; // hlavný program
void main() {
wa = 40;
wb = 5;
clrscr();
pocitaj(wa,wb,wc,wd);
printf("\n%d+(-)%d=%d(%d)",wa,wb,wc,wd);
wc = bez(wa);
printf("\n%d-1=%d",wa,wc);
getchar();
}