Skoky a podprogramy - M8C

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání
Predmet

Konfigurovateľné mikroprocesorové systémy
Tématická časť:
Inštrukcie procesora M8C

Podprogramy

Volanie podprogramu spočíva v uložení parametrov do zásobníka a zmene adresy v registri IP (čítač inštrukcií) na adresu podprogramu s tým, že je uschovaná adresa odkiaľ prevádzame volanie (to aby procesor vedel kam sa má vrátiť). Parametre do zásobníku ukladáme my, zvyšok zariadi inštrukcia CALL.

Ukladanie parametrov do zásobníka

V hlavičke procedúry (alebo funkcie) nájdeme takmer vždy definíciu parametrov volaných:

  • hodnotou - podprogram ich hodnoty iba využíva
  • odkazom - podprogram ich môže čítať a môže do nich i zapísať


Pri volaní hodnotou

Uložíme konkrétne hodnoty (prečítané napr. i z pamäti). Vzhľadom k organizácii zásobníka sú parametre volané hodnotou uložené po slovách nasledovne:

  • parametre o dĺžke jednej slabiky (byte, short int, char, bool) - obsadia celé slovo (pamäťou nešetria)
  • parametre o dĺžke jedného slova (word, int) - obsadia slovo
  • parametre o dĺžke dvojslova (pointer, long int) - obsadia dve slova (ukazovateľ je adresa, do zásobníka teda najskôr uložíme segmentovú a potom offsetovú časť adresy)
  • parametre o dĺžke 6 slabík (float) - obsadia v zásobníku tri slová
  • parametre dlhšie (reťazce, množina, pole, záznamy) - sa ukladajú ako ukazovatele na hodnotu.

Pri volaní odkazom

Uložíme celú adresu miesta (teda segment i offset) odkiaľ sa má hodnota čítať alebo kam sa má zapísať (to je vlastne obsah ukazovateľa na pamäťové miesto).

Samotné volanie podprogramu

Musíme rozlišovať volanie blízkeho podprogramu a vzdialeného. Za vzdialený v tomto prípade považujeme podprogram s adresou v odlišnom segmente. I keď sa pre programátora nič nemení je dobré vedieť, že pri vzdialenom volaní sa mení nie len IP, ale i CS. Označenie miesta skoku nesie teda naviac informáciu o segmentovej adrese. Skok do podprogramu zaistí inštrukcia

CALL

adresa - na vrchol zásobníka ulož obsah (CS pri vzdialenom volaní a) IP a naplň tieto registre adresou uvedenou v parametri (pre nás slovo adresa nahradíme názvom podprogramu)

  • CALL - rozsah podprogram 2 kB, 11-bitová adresa.
  • LCALL - rozsah podprogram 64 kB, 16-bitová adresa.

Ukončení samotného podprogramu zaistí inštrukcia

RET[F]

z vrcholu zásobníka vezmi adresy a dosaď ich do (CS a) IP Volanie podprogramov je teda jednoduché.

Jednoducho napíšeme inštrukciu CALL s menom podprogramu (teda procedúry alebo funkcie). Ostatné zariadi prekladač, ktorý zistí, či sa jedná o blízke alebo vzdialené volanie. Podľa toho dosadí adresu. Návrat si opäť zariadi prekladač pri ukončení podprogramu.

Za volaním programu musíme uvolniť zásobník, teda musíme vybrať toľko hodnôt, koľko sme ich vložili pred volaním podprogramu (počet parametrov podprogramu).

Podprogram 'sčítaj'

Vytvoríme podprogram sčítaj. Najskôr musíme vyriešiť odovzdávanie parametrov podprogramu. Vo vyšších programovacích jazykoch sa pre odovzdanie parametra používa zásobník, my si zatiaľ vystačíme s dohodnutými registrami. Akonáhle vykonáme inštrukciu pre sčítanie ADD, bude hodnota operanda prepísaná výsledkom.

 scitaj:
 add CL, 10
 ret

Volanie progrmu scitaj

 mov CL, 1
 call scitaj

Skoky

Nepodmienený skok

Je to nepodmienený skok na iné miesto programu. To musí byť označené návestím. Za inštrukciou skoku je potom uvedený jeho názov.

JMP

navestie - urob skok programu na návestie (v skutočnosti sa len zmení obsah čítača inštrukcií IP, prípadne CS pri vzdialenom skoku) V programe potom nepodmienený skok vyzerá takto:

 navestie: inštrukcia na ktorú bude odkaz
           .
           .
           JMP navestie

Ak skoky používame, hrozí vždy nebezpečie, že sa program zacyklí (a nikdy neskončí). Preto je dôležité si vždy rozmyslieť, za akých okolností by k tejto kolízii mohlo dôjsť.

Podmienený skok

Jedná sa o skok podmienený stavom jedného alebo viac, bitov registri príznakov F. Len týmto spôsobom je možné prevádzať v assembleri priame vetvenie programu. Pred inštrukciou podmieneného skoku preto vždy prevedieme inštrukciu, ktorá použitý príznak nastaví. V prípade, že nie je splnená podmienka skoku, pokračuje program ďalej, ako by sa nič nedialo. Inštrukcie podmieneného skoku začínajú vždy písmenkom J. Za ním je skratka udávajúca na akých bitoch registru F je skok závislý.


  • JZ návestie - skok na návestie pri ZF = 1
  • JNZ návestie - skok na návestie pri ZF = 0
  • JC návestie - skok na návestie pri CF = 1
  • JNC návestie - skok na návestie pri CF = 0


Pri hľadaní inštrukcie podmieneného skoku musíme myslieť na to, za akých okolností chceme skok vykonať. K tomu je tiež dobré si uvedomiť:

  • A < B => A - B < 0 => SF = 1
  • A = B => A - B = 0 => ZF = 1
  • A > B => A - B > 0 => SF = 0

Použitie podmienkových skokov

Podmienka vetvenia Kód porovnania a vetvenia programu
A==4 CMP A,4
JZ navestie
A<>4 CMP A,4
JNZ navestie
A<4 CMP A,4
JC navestie
A>=4 CMP A,4
JNC navestie
A<=4 CMP A,4
JZ navestie
JC navestie

Rozdiel čísel v tomto prípade prevedieme najlepšie inštrukciou CMP. Pre tvorbu cyklu môžeme použiť jeden z registrov, ktorý si pre krokovaciu premennú vyčleníme. Jednoduchý cyklus potom vytvoríme podmieneným skokom:

 MOV CL, 10  // do registra CL dosaď 10, počet krokov
 nav:
 DEC CL        // odčítaj od CL číslo 1
 JNZ nav       // ak nie je nula skoč na návestie

Program opakuje skok dokiaľ nie je v registri CL nulový výsledok.

LITERATÚRA

  1. http://silent.melias.sk/assembler/obsah.html
  2. http://www.bloog.sk/2009/09/06/assembler-instrukcie-call-a-ret/