Umíme to s Delphi: 114. díl – systémový zavaděč, možnosti překladu

Dnešní článek je rozdělen do dvou částí. V první polovině se podrobněji podíváme na spouštění aplikace a na její zavádění do operační paměti počítače. Vysvětlíme si rozdíl mezi relativní a absolutní adresou a na příkladu si celý proces ukážeme. Druhá část článku je pak věnována překladači Delphi, možnostem jeho spouštění a také skupinám projektů.

V minulém dílu seriálu jsme se zabývali procesy překladu a vkládání souborů. Skončili jsme konstatováním, že výsledkem překladu je spustitelný soubor .EXE, který je následně určen k tomu, aby byl spuštěn. Dnes na tomto místě navážeme popisem toho, jak proces spouštění může vypadat.

Relativní a absolutní adresy a zavaděč

V závěru předchozího článku jsme si uvedli, že výsledkem celého překladu je soubor EXE, který „vyplivne“ linker. Kromě toho jsme zmínili, že pokud chceme tento soubor spustit, dostává se ke slovu systémový zavaděč (loader), který tento soubor zavede do operační paměti a spustí.

V této souvislosti jsme hýřili pojmy „relativní adresa“ a „absolutní adresa“. Přestože tato problematika se již netýká přímo Delphi, věřím, že pro vás bude zajímavé, když alespoň ve stručnosti naznačím, oč jde. Programátorovi totiž asi neuškodí, když zná i některá další témata, která se netýkají jen algoritmizace v jeho oblíbeném vývojovém prostředí.

Jak to tedy s adresami je? Ukážeme si vše prakticky.

Dejme tomu, že máme aplikaci skládající se ze dvou modulů: Uni1 a Unit2. V jednotce Unit1 nadefinujeme lokální celočíselnou proměnnou PEPA:

var Pepa: integer;

V modulu Unit2 pro změnu definujeme lokální proměnnou PAVEL:

var Pavel: integer;

Nyní se pojďme podívat, co s těmito proměnnými provede překladač a jak si s nimi poradí. Podrobnosti nemusí být doslovně tak, jak je uvedu v následujícím textu (jedině Borland asi ví, jak přesně pracuje interně překladač Delphi), nicméně obecně by snad následující informace měly platit:-)

Překladač nejprve dostane k překladu modul Unit1. V rámci své činnosti a v rámci jednotlivých fází, které provádí (lexikální analýza, syntaktická analýza, sémantická analýza apod.) si interně vytváří celou řadu nejrůznějších tabulek, v nichž si interně uchovává informace o zpracovávaném souboru. Tyto tabulky nebudeme podrobně rozebírat, protože to není pro naše účely nutné. Jednou z nich je také tzv. tabulka symbolů, která slouží k uchování informací o všech symbolech a identifikátorech (názvy proměnných, konstant, jména tříd, identifikátory všeho možného, jména funkcí apod.), které se v daném modulu vyskytují. Ke každému symbolu se v tabulce symbolů uchovává celá řada informací: jméno, hloubka zanoření, o jaký symbol jde (proměnná, jméno funkce, konstanta, návěští apod.), typ symbolu (například typ proměnné – celočíselná, reálná apod.), kde je použit (a zda vůbec je použit, z tohoto příznaku pak může překladače třeba generovat varovná hlášení typu „proměnná XXX byla definována, ale nebyla použita“ apod.) a celu řadu dalších údajů.

Jedním z uchovávaných údajů, pro nás v tomto okamžiku nejdůležitějším, je také hodnota symbolu, tedy relativní adresa, na které je (bude) symbol uložen.

Dejme tomu, že v našem konkrétním příkladu stanoví překladač při překladu modulu Unit1, že proměnná PEPA bude v paměti ležet na relativní adrese 1000 (stanovení této hodnoty není jen na jeho libovůli, vyplyne to z průběhu překladu).

O několik vteřin později dostane překladače k překladu modul Unit2. V tom okamžiku samozřejmě už dávno neví o tom, že před chvílí překládal Unit1 a že na adrese 1000 má ležet PEPA. Proto třeba stanoví, že proměnná PAVEL definovaná v modulu Unit2 bude ležet také na adrese 1000.

Výsledkem překladu jsou tedy dva soubory – Unit1.DCU a Unit2.DCU, které si s sebou nesou také nějakou podobu tabulky symbolů (ve skutečnosti je vše trochu složitější, ale v principu nám to nevadí).

Linker následně dostane tyto dva soubory. Zjistí, že aby aplikace mohla fungovat, musí oba tyto soubory být umístěny v operační paměti (což je logické, pokud oba tvoří jeden a tentýž projekt). Překladač ovšem tuto informaci neměl – překládal samozřejmě každý modul odděleně, nezávisle na okolí. Linker tedy nyní musí provést přepočet relativních adres: mezi jinými také adres, na kterých leží PEPA a PAVEL. Linker třeba určí, že ve výsledku budou moduly Unit1 a Unit2 ležet v operační paměti za sebou, přičemž Unit2 bude ležet za Unit1 a Unit1 bude uložen od paměťové adresy 100. Proto provede přepočet všech relativních adres týkající se modulu Unit1 (připočte k nim počáteční adresu 100, takže PEPA bude mít adresu 1100) a přepočet všech relativních adres týkajících se modulu Unit2 (připočte k nim počáteční adresu 100 a také délku, kterou v paměti zabere Unit1, což bude třeba 5000). PAVEL bude tedy ve výsledku mít adresu 1000 (jeho původní relativní adresa) + 100 (počáteční adresa Unit1) + 5000 (délka Unit1) = 6100.

Linker tedy provede přepočet, jehož výsledkem bude informace, že PEPA bude v paměti ležet na adrese 1100 a PAVEL 6100. Tyto adresy nyní musí „napsat“ na všechna místa, která nějak pracují s proměnnými PEPA a PAVEL: pokud byl třeba v původním zdrojovém kódu příkaz typu

PEPA := PEPA + PAVEL;

linker jej změní na příkaz typu:

na adresu 1100 zapiš součet hodnot z adres 1100 a 6100;

To však ještě není všechno. V tomto okamžiku sice linker skončí svou činnost a předá nám spustitelný soubor EXE, který bude obsahovat právě instrukce typu

na adresu 1100 zapiš součet hodnot z adres 1100 a 6100;

nicméně v okamžiku, kdy se rozhodneme tento soubor spustit, vrhne se na něj zmíněný systémový zavaděč (loader), který aplikaci zavede do operační paměti. Ve Windows32 sice má každá aplikace k dispozici svůj vlastní virtuální paměťový prostor, nicméně v obecném případě není zajištěno, že běžící aplikace bude v operační paměti ležet od adresy 0. Pokud tedy loader zavede aplikaci do paměti třeba od adresy 10000, bude nutné provést další přepočty reflektující tuto skutečnost. PEPA tedy nebude ležet na 1100, ale na 1100 + 10000 = 11100, stejně tak PAVEL bude fyzicky umístěn do 6100 + 10000 = 16100. Náš příkaz pro součet PEPY a PAVLA tedy bude nakonec, za běhu aplikace, v operační paměti zapsán takto:

na adresu 11100 zapiš součet hodnot z adres 11100 a 16100;

Zatímco „původní“ adresy 1000, 1100 apod. byly relativní (jinak řečeno byly určeny k pozdějšímu přepočtu a bylo zřejmé, že na nich příslušné symboly nakonec nebudou ležet), adresy 11100 a 16100 (tedy adresy, na kterých PEPA a PAVEL nakonec skutečně leží v operační paměti), se nazývají absolutní.

Vidíte, že problematika překladu není zdaleka tak jednoduchá , jak by se mohlo na první pohled zdát. Z uvedených informací vyplývá, kolik práce musí být provedeno, aby z námi sepsaného kódu (který typicky nestojí ani ze čtvrtiny takovou námahu, jakou je nutné vynaložit jednotlivými nástroji k jeho překladu:)) vytvořen a spuštěn funkční program.

Nastavujeme překladač Delphi

V předchozích článcích a také ve výše uvedených odstavcích jsme si částečně popsali, jak překladač pracuje, jaké činnosti vykonává a do jakých fází můžeme jeho práci rozdělit. Ve zbytku dnešního vánočního článku (a pravděpodobně také v článku příštím) se zaměříme na praktickou stránku věci, tedy na to, jakým způsobem můžeme coby programátoři činnost překladače ovlivňovat a modifikovat.

A začneme od úplného začátku – od spuštění překladače. Při práci v Delphi jsme zvyklí, že po dopsání zdrojových kódů stiskneme klávesu F9 (tj. spustíme vlastně položku Run – Run) a výsledkem je po chvíli spuštěná aplikace. Máme k dispozici ještě jiné možnosti? Které?

Project – Compile: překládáme změněné soubory

Volby spouštějící překlad projektu jsou v Delphi skryty v hlavní nabídce pod položkou Project. Základní volbou je provedení překladu – Compile (klávesová zkratka Ctrl-F9). Compile způsobí spuštění překladače a přeložení všech modulů (jednotek, Units), které tvoří aktuální projekt. Při této volbě jsou ovšem přeloženy pouze ty zdrojové soubory, které byly od posledního překládání nějakým způsobem změněny (modifikovány): nezměněné zdrojové soubory zůstanou beze změny. Poté, co překladač provede překlad, je spuštěn také další známý nástroj – linker, který provede sestavení projektu. Výsledkem je tedy spustitelná aplikace (soubor .EXE nebo .DLL).

Pokud byste chtěli, aby se průběh překladu zobrazoval grafickým ukazatelem, můžete zatrhnout v nabídce Tools – Environment Options na záložce Preferences položku Show Compiler Progress. V takovém případě bude při překládání (a po jeho skončení) zobrazován dialogový box, který znají pravděpodobně programátoři v C++ Builderu (neboť tam je zobrazován implicitně):

Klepněte pro větší obrázek

Tento dialog zůstane zobrazen i po skončení překladu, takže jej budete muset uzavřít stisknutím tlačítka OK, v něž se po úspěšném překladu přemění tlačítko Cancel z předchozího obrázku.

Chcete-li, pojďte se ještě podívat na pravidla, podle kterých postupuje překladač Delphi při vyvolání překladu (Project – Compile):

  • soubor projektu (.DPR) je vždycky znovu přeložen, a to i v případě, že nebyl od posledního překladu změněn;
  • pokud byl změněn zdrojový kód některého modulu (Unit), dojde k jeho přeložení. Poté, co je modul UnitX.PAS přeložen, dojde k vytvoření souboru UnitX.DCU (Delphi Compiled Unit): tak se postupuje pro každý překládaný modul;
  • pokud Delphi nenajde zdrojový soubor jednotky, jednotka samozřejmě není překládána;
  • pokud byla změněna sekce interface jednotky UnitX, jsou znovu přeloženy také všechny další jednotky, které závisí na jednotce UnitX;
  • pokud je jednotka UnitX svázána se souborem .OBJ (externí knihovna), a tato externí knihovna byla změněna, jednotka UnitX je také znovu překompilována;
  • pokud jednotka obsahuje vkládaný soubor (viz minulý díl seriálu), a tento vkládaný soubor byl změněn, jednotka je také znovu překompilována.

Project – Build: překládáme všechny soubory

Tolik k příkazu Compile. Další položkou, kterou naleznete v nabídce Project, je položka Build. Ta se liší od předchozího příkazu (příkazu Compile) pouze tím, že vynutí překlad úplně všech zdrojových souborů projektu, tedy i těch, u nichž nedošlo od minulého překladu k žádným modifikacím. Po překladači se opět dostane ke slovu linker, takže výsledkem je stejně jako v předchozím odstavci spustitelná aplikace .EXE nebo .DLL.

Project – Compile All, Build All: skupiny projektů

Další dva příkazy z nabídky Project se týkají situace, v níž máme v jedné skupině přiřazeno větší množství projektů. Příkazem Compile All Projects zařídíte kompilaci všech projektů dané skupiny s tím, že jsou kompilovány pouze ty soubory, které byly od poslední kompilace změněny. A analogicky platí i čtvrtý příkaz – Build All Projects: k překladu dojde u všech souborů všech projektů dané skupiny, bez ohledu na to, byly-li změněny či nikoliv.

V této souvislosti bychom si měli vysvětlit ony tajuplné „skupiny projektů“, které jsme zmínili v předchozím odstavci, a přitom jsme se s nimi dosud ještě nesetkali. Vytvoření skupiny projektů slouží v situacích, v nichž potřebujeme spravovat několik (například nějak souvisejících) projektů najednou, jednotně. Typická situace spočívá ve vytvoření skupiny projektů s tím, že v této skupině je spustitelný soubor .EXE a jedna nebo více souvisejících dynamických knihoven .DLL. Pokud je sdružíme do projektové skupiny. získáme mimo jiné možnost překládat je všechny současně.

Chceme-li vytvořit skupinu projektů, jednoduše zvolíme View – Project Manager. Project Manager je nástroj pro prohlížení a správu projektů (později si o něm prozradíme více, prozatím vezměte prosím zavděk níže uvedených obrázkem). Pokud není v tuto chvíli otevřen žádný projekt, zobrazuje Project Manager <No Project Group>, opačném případě zobrazuje <ProjectGroup1>.

Klepněte pro větší obrázek

Nyní klepneme na příslušný nápis pravým tlačítkem myši a zvolíme buď Add New Project (pak dojde k zobrazení dialogu pro vytvoření nového projektu) nebo Add Existing Project (pak budeme moci najít na disku existující projekt a přidat jej do skupiny).

Poté, co jsme do skupiny přidali všechny požadované projekty, klepneme na skupinu opět pravým tlačítkem, zvolíme Save a uložíme skupinu projektů na disk.

Pokud se vám nechce zobrazovat pro přidávání nových projektů Project Manager, můžete využít i položky Add New Project a Add Existing Project z nabídky Project v hlavním menu.

Kontrolujeme syntaxi

Předposlední položkou z nabídky Project, na kterou se dnes podíváme, je Syntax Check. Při jeho použití nedochází k žádnému generování souborů (ať už DCU nebo spustitelných EXE, DLL). Volbou Project – Syntax Check dojde sice ke spuštění překladače, ale pouze proto, aby zkontroloval syntaktickou správnost zdrojových souborů.

Vzhledem k tomu, že při této volbě nedochází ke spuštění linkeru a ke generování žádných výstupních souborů, proběhne kontrola syntaxe velmi rychle, podstatně rychleji než celý překlad včetně sestavení. Nabízí se tedy možnost provádět v průběhu psaní zdrojového kódu pouze průběžné kontroly syntaxe a teprve nakonec přeložit celý projekt (příp. skupinu projektů) tradičně, za použití některého z příkazů uvedených výše.

Prohlížíme projektové statistiky

Pokud se chcete pokochat pohledem na počet řádků, které jste již zapsali do zdrojového kódu, můžete využít další položku z nabídky Project: Project – Information. Po jeho zvolení dojde k otevření dialogového okna, které si můžete prohlédnout na následujícím obrázku:

Klepněte pro větší obrázek

Závěrem

Dnešní článek se nejprve pokusil osvětlit rozdíl mezi relativní a absolutní adresací a vysvětlit postup, jakým jsou spustitelné aplikace zaváděny do operační paměti. Ve druhé části jsme se pak zabývali překladačem Delphi a způsobem, jak tento překladač spustit tak, jak sami potřebujeme. Věřím, že jste si alespoň v jedné části článku našli informace, které jsou pro vás zajímavé a užitečné.

Protože dnešní článek je očividně posledním v tomto kalendářním roce, rád bych vám popřál jménem svým i jménem celého autorského kolektivu serveru Živě mnoho zdraví, úspěchů, klidu a optimismu v roce 2004. A budu moc rád, přispějí-li k vašim úspěchům alespoň malým dílkem i další díly tohoto seriálu.

Diskuze (3) Další článek: Antivirus a firewall zdarma: Brnění od Microsoftu v praxi

Témata článku: Software, Programování, Díl, Cancel, Překlad, Předchozí odstavec, Překladače, Linker, Project, Možnost, DEL, Modul, Apod, Spustitelný soubor, Paměťový prostor, Projekt, Adresa, 1000, Tito, Delphi, Uvedený obraz, Výstupní soubor, Celé auto, Typická situace, Toto


Určitě si přečtěte

Pojďme programovat elektroniku: Rádiový čip, který má skoro každá bezdrátová myš

Pojďme programovat elektroniku: Rádiový čip, který má skoro každá bezdrátová myš

** Bezdrátové myši řídí čip od Nordic Semiconductors ** Jeho rádiové vysílače si před lety oblíbila i komunita kutilů ** Dnes si je vyzkoušíme v praxi

Jakub Čížek | 9

USA rozdávají chudým dotované telefony s Androidem. Jsou z Číny a plné virů

USA rozdávají chudým dotované telefony s Androidem. Jsou z Číny a plné virů

** Chudí Američané mohou dosáhnout na dotovaný mobil ** Jeden takový rozdává třeba tamní Virgin Mobile ** Má to jeden háček. Je prošpikovaný malwarem

Jakub Čížek | 42

Nejlepší notebooky do 20 000 Kč. Tipy, co se dnes vyplatí koupit

Nejlepší notebooky do 20 000 Kč. Tipy, co se dnes vyplatí koupit

** S cenou do 20 tisíc lze vybrat solidní notebook na práci i hry ** Přenosné notebooky nabídnou i kovová těla a rychlý hardware ** Na hraní se hodí více peněz, ale na použitelný základ dvacet tisíc stačí

Tomáš Holčík, David Polesný | 50

Dnes nastal konec Windows 7. Ale nepropadejte panice, počítač vám nastartuje i zítra

Dnes nastal konec Windows 7. Ale nepropadejte panice, počítač vám nastartuje i zítra

** Dnes končí podpora Windows 7 a systém formálně umírá ** Co to ale znamená v praxi a bude mi PC fungovat i zítra? ** A mohu i v lednu 2020 zdarma přejít na Windows 10?

Jakub Čížek | 121

10 skrytých nastavení prohlížeče Google Chrome, která se můžou hodit

10 skrytých nastavení prohlížeče Google Chrome, která se můžou hodit

** Prohlížeč Google Chrome ukrývá mnoho zajímavých možností ** Našli jsme deset nejzajímavějších skrytých nastavení ** Můžete si například výrazně vylepšit práci s kartami

Karel Kilián | 18



Aktuální číslo časopisu Computer

Megatest 12 bezdrátových sluchátek

Vyplatí se Apple z bazaru?

Test batohů pro notebooky

Vybíráme nejlepší sportovní hodinky