Ľudmila Jánošíková | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Programovanie v jazyku symbolických adries | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pre 32-bitové procesory Intel | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Procedúry
Procedúry deklarujeme pomocou direktívy PROC. Jej syntax v zjednodušenej podobe môžeme popísať takto: meno_procedúry PROC [jazyk] [uses registre] [parameter1[,parameter2]…] Potom nasleduje telo procedúry. Deklarácia procedúry končí direktívou ENDP: meno_procedúry ENDP Meno procedúry je symbolická adresa prvej
inštrukcie v procedúre.
O položkách [jazyk] a [uses] a o parametroch v direktíve
PROC budeme hovoriť neskôr.
Procedúru vyvoláme pomocou príkazu
call meno_procedúry
(call procedure)
Inštrukcia call
uloží do zásobníka návratovú adresu
a vykoná skok na prvú inštrukciu procedúry. Návratovou adresou je aktuálna hodnota čítača inštrukcií
EIP, t.j. offset inštrukcie, ktorá nasleduje za inštrukciou
call.
Volanie procedúry môže
byť priame a nepriame (podobne ako nepodmienený skok). Pri priamom volaní je
operandom inštrukcie call meno
procedúry, pri nepriamom volaní register alebo pamäťový operand. Inštrukcia call sa prekladá rovnako ako inštrukcia jmp: pri priamom
volaní je operandom displacement, ktorý sa pripočíta k aktuálnej hodnote
čítača inštrukcií.
Návrat z procedúry vykonáva inštrukcia
ret [číslo]
(return from procedure)
Inštrukcia ret
vyberie zo zásobníka
návratovú adresu a uloží ju do registra EIP.
Inštrukcia ret môže mať priamy operand, ktorý sa
po výbere návratovej adresy pripočíta k ukazovateľu zásobníka ESP. To
znamená, že po výbere návratovej adresy sa v zásobníku preskočí toľko
bajtov, koľko udáva operand inštrukcie. Inštrukcia ret
s operandom sa používa vtedy, keď sa do procedúry odovzdávajú
parametre cez zásobník. O parametroch procedúry bude reč onedlho. Nasleduje krátky program, ktorý ilustruje
použitie inštrukcií call a ret.
Vedľa zdrojového textu je uvedený jeho preklad spolu s adresou inštrukcie Všimnite si, že
operandom inštrukcie call
v preloženom kóde je 0FFFFFFF9h = -7, čo je vzdialenosť medzi inštrukciou nasledujúcou za call a prvou inštrukciou procedúry.
Na obr. 15 zároveň môžete sledovať,
ako sa mení obsah registrov EIP a ESP a obsah zásobníka.
.code
Obr. 15. Registre EIP, ESP a zásobník pri volaní procedúry Parametre sa do procedúry môžu
odovzdávať:
Prvý spôsob sa používa pri čistých
assemblerovských programoch, druhý najmä vtedy, keď je assemblerovský program
volaný z programu vo vyššom jazyku. Samozrejme, nič vám nebráni, aby ste parametre
odovzdávali v zásobníku, aj keď je celý program v JSA.
K odovzdávaniu parametrov v registroch niet čo dodať, preto sa
v ďalšom výklade zameriame na parametre v zásobníku. Parametre musíme do zásobníka uložiť predtým,
ako vyvoláme procedúru. V procedúre potom parametre sprístupníme pomocou
nepriameho adresovania s použitím bázového registra EBP. Sledujte
nasledujúci príklad: Napíšte procedúru, ktorá ku všetkým prvkom
poľa typu byte pripočíta zadanú hodnotu.
Parametrami procedúry budú: Zostavíme nielen procedúru, ale aj hlavný
program, aby ste videli celý postup odovzdávania parametrov.
TITLE MASM Procedury Na obr. 16 vidíme stav zásobníka po
inštrukcii call Pripocitaj. Obr. 16. Zásobník po inštrukcii call Pripocitaj Pri deklarácii procedúry v direktíve PROC môžeme
parametrom procedúry priradiť symbolické mená. Potom sa na parametre môžeme
odvolávať pomocou týchto mien, a nie cez nepriamu adresu s registrom EBP.
Procedúra sa stáva čitateľnejšou a nemusíme si pamätať vzdialenosť parametrov od
vrcholu zásobníka. Tým, že parametrom priradíme symbolické mená, stávajú sa
z nich formálne parametre procedúry. Každému formálnemu
parametru môžeme predpísať typ. Ak neuvedieme typ
parametra, predpokladá sa dword.
Teraz sa dostávame
k špecifikácii jazyka v deklarácii procedúry. Táto informuje
prekladač o poradí ukladania parametrov do zásobníka pri volaní procedúry a o
tom, kto ich zo zásobníka odstráni.
Ak definujeme jazyk Pascal,
Basic alebo Fortran, budú sa
parametre ukladať zľava doprava a prekladač bude generovať inštrukciu
ret so správnym operandom. Okrem toho prekladač automaticky
v procedúre generuje inštrukcie pre nastavenie EBP a ESP. V jazyku C
a Prolog sa parametre ukladajú sprava
doľava a prekladač predpokladá, že parametre odstráni volajúci program. V
32-bitových aplikáciách určených pre operačný systém Windows treba zadať
jazyk stdcall. Táto konvencia je zmiešaninou
C a Pascalu. Parametre sa ukladajú do zásobníka sprava doľava a zo zásobníka
ich odstraňuje volaná procedúra.
Konvenciu jazyka môžeme určiť pri definovaní modelu pamäti na začiatku programu. Táto potom platí pre všetky procedúry a netreba ju definovať v každej procedúre zvlášť. V súbore Irvine32.inc je vložený súbor SmallWin.inc, kde je definovaný model pamäti spolu so špecifikáciou stdcall takto:
Procedúra Pripocitaj s formálnymi parametrami bude
vyzerať takto: Pripocitaj PROC paOffset, paDlzka, paCislo:byte Prekladač automaticky doplní na začiatku procedúry príkazy push ebp ktoré slúžia na zachovanie obsahu registra EBP z volajúceho programu. Na konci procedúry automaticky vloží príkazy leave pre obnovenie regitra EBP a návrat z procedúry do volajúceho programu. Inštrukcia leave vykoná to isté ako mov esp,ebp V hlavnom programe sa formálne parametre nahradia skutočnými parametrami takto: main PROC Direktíva INVOKE vykoná to isté ako
push offset Pole Špecifikácia uses
v direktíve PROC definuje registre (maximálne 8
položiek oddelených medzerami), ktorých obsahy budú automaticky na začiatku
procedúry uložené do zásobníka a pred návratom z procedúry opäť
automaticky obnovené, aby sa zachovali ich hodnoty z volajúceho programu.
Ak nie je špecifikovaný jazyk, direktíva uses sa ignoruje.
Procedúra Pripocitaj modifikuje registre EAX, EBX a ECX, preto by jej deklarácia mala vyzerať takto: Pripocitaj PROC USES eax ebx ecx paOffset, paDlzka, paCislo:byte Prekladač automaticky doplní na začiatku procedúry príkazy push ebp |
Načo je vám jazyk symbolických adries?
Architektúra moderných procesorov Služby operačného systému MS-DOS Služby operačného systému Windows 95/98/NT/XP |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Vydala Žilinská univerzita v Žiline, 2000. ISBN 80-7100-723-4. Otázky a pripomienky môžete poslať autorke. Naposledy upravené 19.10.2015. |