Monday, February 25, 2013

SCC4. SmallC - funkcie

Jedna z najväčších výhod C jazyka sú lokálne premenné. Lokálne premenné nemajú miesto vo výslednej binárke, ale sa alokujú dynamicky. Počas behu programu, pri potrebe lokálnej premennej sa na zásobníku alokuje pamäť. Napríklad obyčajný PUSH posunie SP o dva byte. Na vzniknutom mieste môžeme ukladať hodnoty. Pri ukončení potreby lokálnej premennej sa urobí POP. Tým sa zásobník vráti do pôvodného stavu. Skúsme takýto kód
main() {
int la;
la = 5;
}
Začiatok metódy je označený labelom main:
;main() {
main:
Ďalej dostaneme:
;int a;
push b
;a=5;
lxi h,#0
dad sp
push h
lxi h,#5
pop d
call ccpint
Deklarácia premennej v metóde spôsobí okamžitý PUSH aby sa alokoval priestor. Ďalej nasleduje dvojica metód LXI a DAD ktoré nastavia do HL adresu premennej a.
Táto adresa je hneď uložená na stack. Toto je typické pre kód generovaný podľa primary/secondary register konceptu. Pretože nemáme viac registrov, každá hodnota sa musí hneď ukladať na stack aby sa uvoľnili jediné dva registre. Toto je na jednej strane jednoduchšie na implementáciu a aj výsledný asm kód je ľahko čitateľný. Na druhej strane je to veľmi neefektívne. Moderné procesory majú desiatky registrov a namiesto ukladania na stack sa alokujú ďalšie a ďalšie registre. Ale napísať túto časť kompileru (register alocation) patrí medzi najťažšie úlohy.
Ďalej nasleduje načítanie hodnoty 5 do HL a do DE sa popne adresa lokálnej premennej. A zavolá sa rutina z knižnice, ktorá uloží HL na adresu DE. Mimochodom tieto tri inštrukcie sa dajú nahradiť jedinou. Existuje aj nedokumentovaná inštrukcia 8085 s názvom SHLX. Prepínač -u v SmallC zapne generovanie kódu s nedokumentovanými inštrukciami. Pri zapnutí -u sa vo výpise obajví aj ďalšia nedokumentovaná inštruckia - LDSI.

Koniec metódy:
pop b
ret
Pop opraví SP a ret ukončí metódu.
Ako sa zmení kód ak budeme mať dve lokálne premenné ? Nechávam to na vlastné pokusy.

No comments:

Post a Comment