12.7. Preklad do strojoveho kodu
Kompilator normalne kompiluje program a ocakava jeho vypocet s
kompilatorom umiestnenym v pamati. Casto toto moze byt v
kontraste s poziadavkami, nakolko program moze byt pridlhy,
alebo castejsie moze byt zamyslany ako samostatny program, moze
byt normalne loadovany a zbehnuty samostatne bez toho aby
kompilator bol loadovany ako prvy. Pouzitie prikazu:
# translate object_file_name
dava kompilatoru instrukcie nahrat program a vsetky pozadovane
routiny na pasku alebo microdrive pod menom suboru. Tento prikaz
sa musi objavit na zaciatku programu.Pozrite podrobnejsie cast
venovanu preprocesorovym prikazom.
12.8. Obetovanie chybovych sprav (nova cast)
Kompilator vytvara vysvetlujce chybove hlasenia, ktore urcuju
chyby v programe. Tieto hlasenia su ulozene v pamati. Vacsie
programy mozu byt kompilovane ak tato pamat je vyuzita
kompilatorom. Na toto sluzi prikazovy riadok:
# error
Po tomto chyby produkuju len cislo chyby pokial nie je
kompilator opat nahrany.
13. Implicitna deklaracia
14. Revizia typov
14.1. Struktury a zvazky
14.2. Funkcie
14.3. Polia,ukazovatele a indexovanie
14.4. Explicitna zmena ukazovatela
Ukazovatele su 16 bitove adresy pamate Z80 a mozu byt zmenene na
cele 16 bitove cisla. Ukazovatele su ulozene v pamati beznym
sposobom t.j. byte s nizsim vyznamom na nizsej adrese.
15. Vyrazy s konstantami
Hisoft C kompilator vypocitava vyrazy v case kompilacie, tak ze
pocas behu programu ich pozna ako konstanty. Vysledok pozna ako
konstantu ,ak vsetky operandy su konstanty. Neprepocitava vyrazy
,ktore su zname len ciastocne.
16. Uvahy o prenosnosti (Portability considerations)
Argumenty funkcie sa vyhodnocuju zlava doprava.
Konstanty typu character smu byt len jeden znak.
Znaky v stringu su alokovane v poradi rastucich adries
pamati,tak ako prvky pola.
Radime nespoliehat sa na nespecifikovane crty pokial to nieje
absolutne nevyhnutne.Detaily o mnohych implementaciach sa
udavaju na zvysenie zrozumitelnosti a na to pouzitie,kde je to
principialne.Tvrdili sme napr.,ze argumenty funkcii sa
vyhodnocuju zlava doprava.To nemusi platit v nasledujucej verzii
kompilatora.
17. Anachronizmy
Kompilator ich nepodporuje.
3.2 Kompilatorovy Preprocesor
Tento odsek uvadza detaily o preprocesorovej casti kompilatora.
Preprocesorovy prikaz je ten,ktory sa zacina znakom '#'.Prepro-
cesorovy interfejs nieje tak jasne definovany ako samotny jazyk,
lebo rozne systemy maju rozne poziadavky.Prikazy,implementovane
v ZX Spectrum su nasledovne:
3.2.1 #define <idetifier> <macro>
Tento prikaz umoznuje obmedzene budovanie makier a predstavuje
prostriedok,ktorym sa definuju konstanty v C programoch.Text
nasledujuci za #define je normalne meno,ktore by sa pouzilo
namiesto cisla alebo vyrazu,napr. 'EOF' namiesto -1 .Toto je
cast <identifier> prikazu.Cast <macro> je text,ktorym bude
idenifikator nahradeny,kedykolvek sa pouzije v hlavnom programe.
Napriklad ak sme v zahlavi programu mali nasledovne prikazy
preprocesora:
#define EOF -1
#define maximum 1000
tak kdekolvek pouzijeme 'EOF' alebo 'maximum',budu v programe
nahradene '-1' resp. '1000'.Pamatajte,ze ako nahrada sa pouzije
cely text,nasledujuci za <identifier>,takze treba davat pozor na
velmi castu chybu davania bodkociarky za cast <macro>.Ak by sme
napisali
#define EOF -1;
tak kazdy vyskyt 'EOF' bude nahradeny '-1;' ,co obvykle nieje
to,co sme pozadovali! Kernighan a Ritchie umoznuju #define makra
s argumentami,takze ak sa program prenasa z ineho kompilatora,
je treba vsetky makra s argumentami prepisat ako funkcie. Tato
implementacia neumoznuje argumenty pri #define makrach,ani
preprocesorovy prikaz #undef ,ktory sposobi,ze kompilator
zabudne predtym definovane makro, nieje dostupny.
3.2.2 #error
Tento prikaz sposobi jednorazove odstranenie chyboveho hlasenia
kompilatora,uvolnujuc kompilatoru priestor,zaberany touto
spravou.Toto sa normalne pouzije len v obzvlast velkych progra-
moch.Nasledovna detekcia chyby vyvola len objavenie sa cisla
chyby namiesto plneho textu.
3.2.3 #list
Za tymto prikazom nasleduje bud znamienko '+' alebo '-' a tym sa
zapne alebo vypne listing kompilatora.Tieto prikazy mozu byt
kombinovane,takze bezna prax ako dosiahnut pozadovany efekt je
dat #list- na zaciatok zahlavia alebo kniznicneho suboru a
#list+ na jeho koniec.
3.2.4 #direct
Za tymto prikazom tiez nasleduje '+' alebo '-' a pouziva sa na
zapnutie alebo vypnutie modu priameho vykonavania.Tento mod je
takmer urcite vynimocny len pre kompilator Hisoft C a umoznuje
testovanie programov a funkcii hned ako su pisane.
Ak bol raz vydany prikaz #direct+,mozno priradovat
premenne,zbiehat cykly a vykonavat vsetky ostatne prikazy.Po
napisani mena funkcie,za tym parametre a bodkociarku, funkcia sa
vykona.Obvykle je to vyhodne len ked funkcia tlaci svoje
vysledky:
#direct+
printf("%u v hexa je %x\n",3000,3000);
#direct-vypise dekadicky a hexadecimalny ekvivalent 3000 na obrazovku.
#direct- bolo pouzite na ukoncenie modu priameho vykonavania.
Pamatajte si,ze pokus o vyvolanie neexistujucej funkcie sposobi
skok na nahodne miesto,co takmer vzdy znamena spadnutie systemu
a treba znovu nahrat kompilator.
3.2.5 #include
Tento prikaz je zrejme najuzitocnejsie povazovat za prikaz na
spustenie kompilatora hoci jeho presnym efektom je zahrnutie
specifikovaneho suboru do kompilacie ineho. Ma tri zakladne
formy, a to:
#includeTakto sa skompiluje program,ktory sa ako zdrojovy nachadza v
oblasti pamate editora.Tento program moze obsahovat dalsie dire-
ktivy #include,ale nie tohto typu.
#include menosuboru alebo
#include "menosuboru" alebo
#include <menosuboru>
Tento prikaz sposobi,ze menovany subor bude zahrnuty do prebie-
hajucej kompilacie,co moze znamenat,ze uvedeny subor bude kompi-
lovany,ak to bolo vydane ako samostatny prikaz.Ak je tento pri-
kaz castou ineho suboru,tak sa menovany subor zahrnie do kompi-
lacie suboru,ktory ho volal.Subor zahrnuty do kompilacie ineho
suboru nesmie sam obsahovat dalsie direktivy #include.Vsetky tri
horeuvedene formy su ekvivalentne.
#include ?menosuboru?
Tato obmena umoznuje zahrnutie kniznicneho suboru.V mnohych
ohladoch to tiez umoznuje uzivatelovi podmienenu kompilaciu,lebo
kompiluje len tie funkcie v uvedenom subore,ktorych mena boli
pouzite niekde v hlavnom subore.
Prikaz je obvykle poslednou instrukciou suboru a jeho vplyvom sa
prebehne uvedena kniznica a vyhladaju sa volane funkcie.Ked sa
niektora najde,je skompilovana do aktualneho programu.To znamena
ze ak niekto pouzije standardnu kniznicu aby dostal do programu
iste funkcie,nieje nutne separovat vsetky pouzite funkcie do
zvlastneho suboru a ten normalne zahrnut.Avsak,kedze kompilator
zahrnie len tie funkcie,ktore boli volane,ale nedefinovane,treba
dat pozor aby bolo zaistene,ze vsetky kniznicne funkcie,ktore
volaju ine kniznicne funkcie sa nachadzaju v kniznicnom subore
PRED volanymi.Inymi slovami ak program pouziva funkciu f() a
tato funkcia vola dalsiu funkciu g(),kde f() aj g() su v knizni-
ci,tak definicia f() sa musi nachadzat pred definiciou g().Stan-
dardna kniznica poskytovana s Hisoft C je konstruovana tymto
sposobom,takze by sa nemali pri jej uzivani vyskytnut ziadne
problemy.
3.2.6 #translate menosuboru
Tento prikaz preprocesora oznami kompilatoru,ze strojovy kod,
ktory vznikne kompilaciou vasho programu bude samostatnym kodom,
t.j. vysledok kompilacie sa musi nahrat na pasku alebo micro-
drive pod uvedenym nazvom.Tento prikaz sa obvykle dava az po
uplnom otestovani programu,lebo je neuzitocne mat nefungujuci
samostatny program.
Pri normalnej cinnosti sa kompilator nachadza v pamati spolu so
strojovym kodom,ktory vytvoril.Vo vacsine aplikacii je to plne
akceptovatelne,ale su pripady kedy by bolo vhodnejsie aby
program bezal sam,bez potreby nahravat kompilator a kompilovat
program pred jeho pouzitim. #translate dava tuto moznost a
vysledny subor je program v strojovom kode, ktory mozno nahrat a
zbehnut normalnym pouzitim LOAD "menosuboru" CODE a prikazom
RANDOMIZE USR 25200 .
3.2.7 Ostatne prikazy preprocesora
Hoci Kernighan a Ritchie spominaju niekolko dalsich prikazov
preprocesora,ako #line a #undef,tieto niesu implementovane v
nasom kompilatore.Je to vacsinou preto, ze niesu potrebne v pod-
mienkach,v ktorych pracuje kompilator (ktore vytvara).
3.3 Vysvetlivky
Tieto poznamky su uvedene pre motivaciu a vysvetlenie niektorych
aspektov programovacieho jazyka C a kompilatora Hisoft C.
Kontrola typov
Premenne v C programoch su vzdy urciteho typu,ktory moze byt
jednym z preddefinovanych typov,alebo uzivatelom deklarovany
typ pomocou deklaracie typedef,alebo anonymny typ (napr. int
*(*f())[]).C kompilator kontroluje,ci su premenne vo vyrazoch
kompatibilne aby pomohol odhalit programovacie chyby. V C sa to
kontroluje metodou znamou ako STRUKTURNA EKVIVALENCIA.To zname-
na,ze dve premenne su toho isteho typu,ak ich deklaracie maju tu
istu strukturu,bez ohladu na to kde su deklarovane.Tato poznamka
plati aj ked su pouzite operatory ako * (indirection) alebo
& (address). takze napriklad pre:
int polar [2];
typedef complex[2];
complex z;
int (*ptr_Cartesian)[2];
su polar, z, *ptr_Cartesian vsetky rovnakeho typu.Toto je roz-
diel oproti niektorym inym jazykom,kde potrebuju mat to iste
meno typu alebo byt deklarovane na tom istom mieste,aby boli
ekvivalentne. Strukturalny typ ekvivalencie je flexibilnejsi,ale
moze viest k mimoriadnym zadrhelom pri nespravnom pouziti a je
obvykle vhodne dat mena komplikovanym typom za pomoci typedef.
3.4 Prisposobenie na nizkej urovni.
Tento odsek uvadza niektore detaily o strojovom kode,produkova-
nom kompilatorom,so zvlastnym dorazom na rozmiestenie v pamati a
vyuzitie stroja.Jejho ucelom je pomoct Vam prisposobit ine
programy k programom v C a obzvlast pomoct Vam pri pouziti pri-
kazu "inline".
3.4.1 Format zdrojoveho textu
Zdrojovy text C je vpodstate retazec ASCII znakov,rozdelenych do
riadkov znakom NEWLINE (10, znamy ako LINE-FEED).Niesu tam znaky
CARRIAGE-RETURN (13),hoci tieto budu v zdrojovom texte akcepto-
vane kompilatorom,takze aj ine editory ci dokonca pocitace mozno
pouzit ako prostriedky na tvorbu programov Hisoft C.
3.4.2 Format suborov
Subory su vytvorene na urovni znakov (napr. fopen, getc,
putc,fclose).
Na kazete su subory ulozene ako postupnost data blokov,ktore na-
sleduju za blokom hlavicky.Tento blok je normalna hlavicka
Spectrum.Vsetky data bloky maju 514 bytov a obsahuju: pocet
znakov v prvych dvoch bytoch a maximalne 512 znakov vo zvysku
bloku.Najvyssi bit v pocitadle znakov indikuje posledny blok
suboru.
Na microdrive su pouzite normalne Spectrum CODE,az na to,ze je
pouzita startovacia adresa a dlzka 0.To znamena,ze vacsina roz-
sirenych katalogizacnych programov pre ZX Microdrive oznami
dlzku suboru 0.
Kompilator a kompilovane programy mozu otvorit kazdy typ suboru
na Microdrive pre citanie.Robi sa to automaticky .
3.4.3 Linkovanie funkcii zasobnik
Zasobnik procesora Z80 je pouzity na linkovanie funkcii a
lokalnych premennych.
Volac vycisli kazdy argument zlava do prava a ulozi ich do
zasobnika v obratenom poradi predtym ako zavola funkciu ( takze
posledny argument je na vrchu zasobnika ). MUSI TAM BYT PRESNE
TOLKO ARGUMENTOV KOLKO VYZADUJE FUNKCIA. Na odstartovanie
funkcie volac potom zavedie funkciu s instrukciou CALL.
Volana funkcia v prvom rade ulozi IX register do zasobnika a
naplni ho okamzitou hodnotou ukazovatela zasobnika (SP). Potom
sa funkcia vykonava pouzivajuc IX na dosiahnutie argumentov a
ich umiestneni. Nakoniec obnovi predoslu hodnotu IX ( pre volac)
zozbiera navratove spoje, a odhodi lokalne premenne, spojovace a
ARGUMENTY zo zasobnika.
Vysledok funkcie je v HL a tiez v BC.
Pre variadicke funkcie (t.j. take ktore maju premenny pocet
argumentov ) je uzity podobny mechanizmus. V tomto pripade, po
odlozeni vsetkych argumentov do zasobnika vlozi volac sucet
poctu bytov argumentov , obsahujuci dva byte pre samotny sucet.
Volana funkcia moze pouzit tento sucet na to aby mala pristup k
svojim dalsim argumentom a MUSI ich pouzit pri odhadzovani
argumentov zo zasobnika pred navratom.